BFS-Specific
What is this?
BFS explores in rings: everything one step away, then everything two steps away. That ordering is the whole value — the first time you reach a node, you have reached it in the fewest possible steps, so the level number is the shortest distance and no further checking is needed.
The two problems here push on that in different directions. One needs to traverse edges the wrong way while still remembering which way they pointed. The other needs not one shortest path but every shortest path, which BFS alone cannot give you.
💡 Fun fact: Word Ladder II is a good demonstration that BFS finds a shortest path but not all of them. The fix is to run BFS level by level, recording for each word every predecessor that reached it at that level — not just the first — and to delete visited words only at the end of a level rather than on discovery. Two words on the same level can legitimately both lead to a third; removing a word as soon as it is seen silently discards entire valid paths.
🔓 The 2 problems in this chapter are free. Sign in with Google or Microsoft to start solving.
The one-line idea: BFS gives shortest distances for free because of the order it visits things. To get more than one shortest path, record parents during the walk instead of just distances, and finish each level before marking anything as consumed.
1. Traverse against direction, remember direction
Reorder Routes to Make All Paths Lead to the City Zero has n cities and n − 1 directed roads that form a tree if direction is ignored. You must reverse the fewest roads so every city can reach city 0.
The trick is to store each edge twice: once forward with a cost of 1, once backward with a cost of 0.
adj = defaultdict(list)
for a, b in connections:
adj[a].append((b, 1)) # a → b costs 1 to traverse "the wrong way" from 0
adj[b].append((a, 0)) # b → a is free
Now walk outward from city 0 through the undirected tree and add up the costs. An edge costing 1 is one that points away from the city 0 — exactly the ones needing reversal. The graph structure lets you ignore direction while the weights preserve it.
2. Record parents, not just distances
For all shortest paths, the BFS state changes shape:
parents = defaultdict(set) # word -> every predecessor that reached it first
current = {beginWord}
while current and endWord not in parents:
next_level = defaultdict(set)
for word in current:
for nxt in neighbours(word):
if nxt not in visited: # not seen in an EARLIER level
next_level[nxt].add(word)
visited |= set(next_level) # remove only after the level completes
for w, ps in next_level.items():
parents[w] |= ps
current = set(next_level)
Then a backwards DFS from endWord through parents enumerates every shortest sequence. The two disciplines that make it correct: delete visited words after the level, not during it, and stop expanding once the target appears — anything found later is by definition longer.
3. A 30-second worked example (Reorder Routes)
Roads 0→1, 1→3, 2→3, 4→0, 4→5:
Every edge is examined once, and its cost was decided when the adjacency list was built — the traversal itself needs no direction logic at all.
4. Where you'll actually meet this
- Network reconfiguration. Reorienting links so every node can reach a gateway is the routes problem exactly.
- Word games and spell-checking. Transformation ladders underpin "did you mean" suggestions built on edit-distance graphs.
- Social distance. Degrees of separation, and enumerating all shortest connection chains between two people.
- Routing protocols. Hop-count shortest paths, and equal-cost multi-path routing — which is literally "all shortest paths".
- Puzzle and game solvers. Minimum-move solutions where every move costs the same.
5. Problems in this chapter
▶ Reorder Routes to Make All Paths Lead to the City Zero
Reverse the fewest directed roads so every city reaches city 0. Store each edge twice with costs 1 and 0, then sum the costs on a walk outward from 0.
Pattern: undirected traversal with direction encoded in weights. Target: O(V + E) time, O(V + E) space.
▶ Word Ladder II
Find every shortest transformation sequence between two words. Level-by-level BFS recording all parents, then a backwards DFS to enumerate the paths.
Pattern: BFS parent graph + backward DFS. Target: O(N · L²) for the BFS with wildcard bucketing, plus output size for the enumeration.
6. Common pitfalls 🚫
- Marking words visited on discovery in Word Ladder II. Two words at the same level may both reach a third; removing it early discards valid paths.
- Continuing BFS past the target's level. Any path found afterwards is longer and must not be included.
- Generating neighbours by scanning the whole word list. Use wildcard buckets (
h*t) so neighbour lookup isO(L)rather thanO(N·L). - Forgetting
endWordmay be absent from the dictionary — then no sequence exists and the answer is empty. - Adding direction logic to the traversal in Reorder Routes. Encode it in the edge weight when building the adjacency list and the walk stays trivial.
- Treating the road network as directed for the traversal itself. It is a tree only when direction is ignored; that is what guarantees each city is reached exactly once.
- Using DFS for shortest paths on an unweighted graph. It finds a path, not the shortest one.
7. Key takeaways
- First arrival is shortest arrival. That is what BFS buys, and why no relaxation step is needed.
- Encode awkward semantics in the edge weights so the traversal itself stays simple.
- Record parents to recover paths — distances alone can never reconstruct them.
- Finish the level before marking anything consumed, or you lose alternative shortest paths.
- Stop at the target's level. Later discoveries are strictly longer.
- Bucket neighbours by wildcard when the graph is implicit rather than given.
- Why interviewers like it: everyone can write BFS. Whether you can bend it to produce all optimal answers, and whether you know where the direction information should live, is the differentiator.
Order: Reorder Routes to Make All Paths Lead to the City Zero → Word Ladder II.
Reorder Routes to Make All Paths Lead to the City Zero
Core idea: The roads form a tree, so the underlying connections are fixed — only the arrows are wrong. Walk the tree outward from city
0over the connections (ignoring arrows). Every edge whose original arrow points away from0is pointing the wrong way for someone trying to reach0, so it must be flipped. Count those.
Problem, rephrased
You manage the road network of a region with n cities, numbered 0 to n - 1, joined by exactly n - 1 one-way roads laid out so that, ignoring direction, there is exactly one route between any two cities — a tree. You're given the integer n and a list connections, where connections[i] = [a, b] means a one-way road points from city a to city b.
This year the capital, city 0, hosts a national event, and every city must be able to drive into city 0. Return the minimum number of roads whose direction must be reversed so that every city can reach city 0. It is always achievable: because the underlying network is a tree, only the arrows can be wrong, never the connections.
Strip the story away and this is Reorder Routes to Make All Paths Lead to the City Zero (LeetCode 1466): in a directed tree on n nodes, count the edges oriented away from node 0 — exactly the edges that must be flipped so every node has a directed path to node 0.
Input / Output
n |
connections (a → b) |
Output | Why |
|---|---|---|---|
| 6 | [[0,1],[1,3],[2,3],[4,0],[4,5]] |
3 |
Three roads point away from city 0 |
| 5 | [[1,0],[1,2],[3,2],[3,4]] |
2 |
Two roads must be flipped |
| 3 | [[1,0],[2,0]] |
0 |
Both roads already aim at city 0 |
| 4 | [[0,1],[0,2],[0,3]] |
3 |
A "fountain" — all roads flow out of 0 |
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson