Critical Connections in a Network
Tarjan's DFS: an edge is a bridge only if nothing in the child's subtree can reach back past it
A single DFS pass answers this without ever actually removing an edge. Give every node a discovery time, then track its low-link: the earliest discovery time reachable from that node's subtree using at most one back-edge. When a child's low-link can only reach back down to itself or later — never past its parent's own discovery time — the tree edge connecting them is the ONLY way between the two halves it separates, so removing it disconnects the graph. Any edge that sits on a cycle always has a back-edge shortcut lowering some descendant's low-link past the parent, so it survives.
Details
Animated on: 7 nodes, undirected: two triangles (0-1-2 and 3-4-5) joined by edge (2,3), plus a pendant leaf 6 hanging off 5 — which edges are bridges?
Problem:Critical Connections in a NetworkHard
Tarjan's DFS: an edge is a bridge only if nothing in the child's subtree can reach back past it
step 1 / 16
Badge = discovery time / lowest reachable time
Call stack
Start the DFS at node 0: give it discovery time 0 and set its low-link to the same value — the low-link only ever drops from here, never rises.
1FUNCTION findBridges(n, edges):2 BUILD adj FROM edges3 tin, low <- ARRAY OF n VALUES -14 timer <- 05 FUNCTION dfs(u, parent):6 tin[u], low[u] <- timer7 timer <- timer + 18 FOR EACH v IN adj[u]9 IF v = parent CONTINUE10 ELSE IF tin[v] = -111 dfs(v, u)12 low[u] <- MIN(low[u], low[v])13 IF low[v] > tin[u]14 APPEND (u, v) TO bridges15 ELSE16 low[u] <- MIN(low[u], tin[v])17 dfs(0, -1)18 RETURN bridges
← / → step · space play · Home restart
Every step in words
Show all 16 steps
- Start the DFS at node 0: give it discovery time 0 and set its low-link to the same value — the low-link only ever drops from here, never rises.
- Descend into node 1 from 0: discovery time 1, low-link 1. Every node on the current call stack (0, 1) is an ancestor that 1 could still report a shortcut back to.
- Descend into node 2 from 1: discovery time 2, low-link 2. Every node on the current call stack (0, 1, 2) is an ancestor that 2 could still report a shortcut back to.
- Node 2 also reaches already-visited node 0 directly — a back-edge, not a tree edge. 0 was discovered at time 0, earlier than 2, so 2's low-link drops to 0: there is a shortcut from here straight up to an ancestor, skipping the tree path entirely.
- Descend into node 3 from 2: discovery time 3, low-link 3. Every node on the current call stack (0, 1, 2, 3) is an ancestor that 3 could still report a shortcut back to.
- Descend into node 4 from 3: discovery time 4, low-link 4. Every node on the current call stack (0, 1, 2, 3, 4) is an ancestor that 4 could still report a shortcut back to.
- Descend into node 5 from 4: discovery time 5, low-link 5. Every node on the current call stack (0, 1, 2, 3, 4, 5) is an ancestor that 5 could still report a shortcut back to.
- Node 5 also reaches already-visited node 3 directly — a back-edge, not a tree edge. 3 was discovered at time 3, earlier than 5, so 5's low-link drops to 3: there is a shortcut from here straight up to an ancestor, skipping the tree path entirely.
- Descend into node 6 from 5: discovery time 6, low-link 6. Every node on the current call stack (0, 1, 2, 3, 4, 5, 6) is an ancestor that 6 could still report a shortcut back to.
- Back from 6: its low-link is 6, which is HIGHER than 5's own discovery time 5 — nothing in 6's subtree can reach 5 or anything above it any other way. Edge (5, 6) is a bridge.
- Back from 5: its low-link 3 reaches at or before 4's discovery time 4, so 5's subtree has another way up to 4 or an ancestor. 4's own low-link drops to 3. Edge (4, 5) is not a bridge.
- Back from 4: its low-link 3 reaches at or before 3's discovery time 3, so 4's subtree has another way up to 3 or an ancestor. 3's own low-link drops to 3. Edge (3, 4) is not a bridge.
- Back from 3: its low-link is 3, which is HIGHER than 2's own discovery time 2 — nothing in 3's subtree can reach 2 or anything above it any other way. Edge (2, 3) is a bridge.
- Back from 2: its low-link 0 reaches at or before 1's discovery time 1, so 2's subtree has another way up to 1 or an ancestor. 1's own low-link drops to 0. Edge (1, 2) is not a bridge.
- Back from 1: its low-link 0 reaches at or before 0's discovery time 0, so 1's subtree has another way up to 0 or an ancestor. 0's own low-link drops to 0. Edge (0, 1) is not a bridge.
- DFS complete. 2 bridges found: (5, 6), (2, 3). Every other edge belongs to a triangle, so a cycle already backs it up if it were removed.
Now solve it yourself
Watching is the first half. The second is writing it without the animation.