Articulation Point
Tarjan's low-link DFS: a cut vertex is one no child subtree can climb past
Run one DFS and give every node two numbers: tin, the order it was first reached, and low, the earliest tin reachable from its subtree using at most one back edge. A non-root node u is an articulation point the moment some child v cannot climb back past u — low[v] >= tin[u] — because then u is the only link holding that child's subtree to the rest of the graph. The root is a special case: it has no ancestor to climb toward, so it is a cut vertex only if the DFS had to start two or more separate child branches from it.
Details
Animated on: n = 5, edges = [[0,1],[1,2],[2,0],[1,3],[3,4]] (undirected, connected) — find every node whose removal disconnects the graph.
Problem:Articulation PointHard
Tarjan's low-link DFS: a cut vertex is one no child subtree can climb past
step 1 / 15
Undirected connected graph
5 nodes, 5 edges. A node is an articulation point if deleting it splits the graph into more pieces. One DFS finds every one: track how far back up the tree each subtree can still reach.
1FUNCTION findArticulationPoints(n, adj):2 tin, low <- ARRAY of -1, size n; timer <- 0; ans <- EMPTY SET3 FUNCTION dfs(u, parent, children):4 tin[u] <- timer; low[u] <- timer; timer <- timer + 15 FOR EACH v IN adj[u]6 IF v = parent: CONTINUE7 IF tin[v] != -1: low[u] <- MIN(low[u], tin[v])8 ELSE9 dfs(v, u); low[u] <- MIN(low[u], low[v]); children <- children + 110 IF parent != -1 AND low[v] >= tin[u]: ADD u TO ans11 IF parent = -1 AND children > 1: ADD u TO ans12 dfs(0, -1, 0)13 RETURN ans
← / → step · space play · Home restart
Every step in words
Show all 15 steps
- 5 nodes, 5 edges. A node is an articulation point if deleting it splits the graph into more pieces. One DFS finds every one: track how far back up the tree each subtree can still reach.
- Enter 0 — the DFS root: tin[0] = low[0] = 0, the order it was first reached.
- Enter 1 from 0: tin[1] = low[1] = 1, the order it was first reached.
- Enter 2 from 1: tin[2] = low[2] = 2, the order it was first reached.
- 0 is already visited and isn't 2's parent, so 2-0 is a BACK EDGE reaching an ancestor: low[2] = min(2, tin[0]=0) = 0.
- Back at 1 after finishing child 2: low[1] = min(1, low[2]=0) = 0.
- Enter 3 from 1: tin[3] = low[3] = 3, the order it was first reached.
- Enter 4 from 3: tin[4] = low[4] = 4, the order it was first reached.
- Back at 3 after finishing child 4: low[3] = min(3, low[4]=4) = 3.
- low[4]=4 >= tin[3]=3, so 4's subtree has no edge back above 3 — removing 3 would strand it. Mark 3.
- Back at 1 after finishing child 3: low[1] = min(0, low[3]=3) = 0.
- low[3]=3 >= tin[1]=1, so 3's subtree has no edge back above 1 — removing 1 would strand it. Mark 1.
- Back at 0 after finishing child 1: low[0] = min(0, low[1]=0) = 0.
- 2 is already visited and isn't 0's parent, so 0-2 is a BACK EDGE reaching an ancestor: low[0] = min(0, tin[2]=2) = 0.
- DFS is done. RETURN [1, 3] — removing either one increases the number of connected pieces.
Now solve it yourself
Watching is the first half. The second is writing it without the animation.