Minimum Edges to Reverse to Reach a Node is a classic graph problem that hides a beautiful trick: a shortest-path question where every edge weighs either 0 or 1. That special structure unlocks a faster algorithm than Dijkstra — 0-1 BFS with a double-ended queue.
Problem. You are given a directed graph with n nodes and a source node. You may reverse any
edge, but each reversal costs 1. Find the minimum number of reversals needed to reach every node from
the source.
Example: edges 0→1, 0→2, 1→3, 2→1, 4→2, source 0 → answer [0, 0, 0, 0, 1]. Every node is reachable
for free except node 4, which needs one reversal (flip 4→2 into 2→4).
The slow way first
You could try every combination of reversals and run a search each time — hopelessly exponential. A better-but-heavier idea is to build a weighted graph and run Dijkstra with a heap: that is O(E log V).
But look closer at the weights. Every edge costs exactly 0 or 1. When weights are only 0 and 1, a heap is overkill — we can get O(V + E) instead.
The idea: model reversals as weights, then 0-1 BFS
Rebuild the graph so the cost of reaching a node is the number of reversals. For every original edge u→v:
- add
u→vwith weight 0 — walking along the arrow is free, - add
v→uwith weight 1 — going against the arrow is one reversal.
Now "fewest reversals" is just "shortest path" in this 0/1-weighted graph. Run 0-1 BFS: keep nodes in a deque. When you relax a weight-0 edge, push the neighbor to the front; for a weight-1 edge, push it to the back. The front always holds the cheapest unsettled node, so each node is finalized correctly without a heap.
The key insight: a deque mimics a priority queue when there are only two weights. Weight-0 neighbors are as cheap as the current node, so they go to the front; weight-1 neighbors are one more, so they go to the back.
Walk through it
Step through the animation. We start at node 0 with distance 0. Forward edges 0→1 and 0→2 cost nothing, so nodes 1 and 2 get distance 0 and jump to the front of the deque. To reach node 4 we must reverse 4→2, paying 1, so it lands at the back with distance 1. The deque ordering means we always settle the cheapest node next, and we finish with dist = [0, 0, 0, 0, 1].
Pseudocode
build graph: for each edge u->v
add u->v with weight 0
add v->u with weight 1
dist[everything] = infinity, dist[src] = 0
deque = [src]
while deque is not empty:
u = pop from the FRONT
for each (v, w) in graph[u]:
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
if w == 0: push v to the FRONT
else: push v to the BACK
return distThe Python solution
def min_reversals(n, edges, src):
from collections import deque
graph = [[] for _ in range(n)]
for u, v in edges:
graph[u].append((v, 0)) # walk forward: free
graph[v].append((u, 1)) # reverse: cost 1
dist = [float("inf")] * n
dist[src] = 0
dq = deque([src])
while dq:
u = dq.popleft()
for v, w in graph[u]:
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
if w == 0:
dq.appendleft(v)
else:
dq.append(v)
return dist- We build an adjacency list where each entry is a
(neighbor, weight)pair. - Each original edge contributes two entries: the free forward edge and the cost-1 reversed edge.
dist[src] = 0seeds the source; every other distance starts at infinity.- The
whileloop pops from the front of the deque each time. - Lines 14-18 are the heart of 0-1 BFS: on a better distance, a weight-0 edge pushes the neighbor to the front (
appendleft), a weight-1 edge pushes it to the back (append). - Because the front always holds a minimum-distance node, no heap is needed.
Complexity
| Case | Time | Notes |
|---|---|---|
| Dijkstra with a heap | O(E log V) (moderate) | works, but heavier |
| 0-1 BFS (this solution) | O(V + E) (moderate) | deque, no log factor |
O(V + E) (moderate)We turn a reversal-counting problem into a shortest-path problem, then exploit the 0/1 weights to drop the log factor. Each node enters the deque a small constant number of times, giving linear time.
When this pattern shows up
Whenever edge weights are only 0 and 1 (or you can model a choice as free vs cost-1), reach for 0-1 BFS with a deque instead of Dijkstra. Grid problems with free moves and cost-1 moves, "minimum flips," and "minimum reversals" all fit this mold.
The deque rule is directional: weight-0 neighbors go to the front, weight-1 neighbors to the back. Swap them and the front no longer holds the cheapest node, so distances come out wrong.
Practice
After popping node 2 (distance 0), which node does the reversed edge 2→4 reach, and what distance does it get?
1. Why can we use 0-1 BFS instead of Dijkstra here?
2. How is a single original edge u→v represented in the weighted graph?
3. When we relax a weight-0 edge in 0-1 BFS, where does the neighbor go?
4. What is the time complexity of the 0-1 BFS solution?