3.5.8Graphs

Strongly Connected Components (SCC) — Kosaraju's algorithm, Tarjan's algorithm

2,138 words10 min readdifficulty · medium6 backlinks

What exactly is an SCC?

Figure — Strongly Connected Components (SCC) — Kosaraju's algorithm, Tarjan's algorithm

Kosaraju's algorithm — two passes of DFS

WHY does this work? (derive it, don't memorize)

Key fact about finish times. Suppose SCCs AA and BB exist with an edge ABA \to B in the condensation (so AA comes "before" BB). Then: maxuAf(u)  >  maxvBf(v)\max_{u \in A} f(u) \;>\; \max_{v \in B} f(v) i.e. the SCC that is "earlier" in the DAG finishes later.

Proof sketch (Why this is true):

  • Case 1: DFS first enters AA. Since AA can reach BB, DFS will explore all of AA and BB before returning, so the first node touched in AA finishes after everything in BB. ✓
  • Case 2: DFS first enters BB. Because the condensation is a DAG and edge goes ABA\to B, there is no path BAB \to A. So BB's DFS finishes entirely without touching AA. Later DFS starts in AAAA finishes after BB. ✓

Now reverse the graph. In GrevG^{\text{rev}}, the edge becomes BAB \to A. We start the second DFS from the vertex of highest finish time — that vertex lies in a "source" SCC of the original DAG (no SCC finishes later). In GrevG^{\text{rev}} that SCC is a sink: its edges to other SCCs are reversed and now point into it, so the DFS cannot escape to another SCC. Hence one DFS tree = exactly one SCC. Removing it, repeat. ∎


Tarjan's algorithm — one pass of DFS

WHY low[u] == disc[u] marks a root

  • We keep nodes of the current DFS path/SCC-candidates on an explicit stack, with an onStack[] flag.
  • low[u] says "the earliest-discovered node uu can loop back to without leaving the current SCC."
  • If uu can reach an earlier node (low[u]<disc[u]low[u] < disc[u]), then uu isn't the entry of its SCC — some ancestor is.
  • If uu cannot climb above itself (low[u]==disc[u]low[u]==disc[u]), uu is the highest node of its SCC = its root. Pop the stack down to uu; those vertices are one SCC.

Recall Feynman: explain to a 12-year-old

Imagine cities connected by one-way roads. A "club" is a group of cities where you can drive from any city to any other and come back — a round trip is always possible. That club is an SCC. Kosaraju explores every city twice: first to note the order people finish their tour, then it flips all the road directions and re-tours starting from whoever finished last — each new tour fences off exactly one club. Tarjan is the smart traveler who does it in one go: he keeps a stack of "cities I might still loop back to," and the moment he realizes a city can't reach anyone older than itself, he knows that city is the leader of a club and scoops everyone above it off the stack.


Flashcards

What is an SCC in a directed graph?
A maximal set of vertices where every pair is mutually reachable (paths both directions).
What is the condensation of a graph?
Contract each SCC to one node; the result is always a DAG.
Kosaraju's three steps?
(1) DFS on G recording finish times; (2) reverse the graph; (3) DFS on reversed graph in decreasing finish-time order — each tree is an SCC.
Why does the highest-finish-time vertex matter in Kosaraju?
It lies in a source SCC of the original DAG = a sink SCC in the reversed graph, so its DFS tree can't leak into other SCCs.
In Tarjan, what does low[u] mean?
The smallest discovery index reachable from u via tree edges plus at most one edge to a node still on the stack.
Tarjan condition for an SCC root?
low[u] == disc[u]; pop the stack down to and including u to form the SCC.
Tarjan: when to use low[v] vs disc[v]?
low[v] for tree edges (recursive child); disc[v] only when onStack[v] for back/cross edges.
Time complexity of both algorithms?
O(V+E).
Why is onStack[] needed in Tarjan?
To ignore edges into already-finished SCCs, so separate components don't get merged.
Difference between SCC and undirected connected component?
SCC needs mutual (two-way) reachability; undirected components only need a single path.

Connections

  • Depth First Search — both algorithms are DFS skeletons.
  • Topological Sort — the condensation DAG can be topologically ordered.
  • Directed Acyclic Graph (DAG) — what you get after contracting SCCs.
  • 2-SAT — solved by SCCs on the implication graph.
  • Bridges and Articulation Points — Tarjan's low-value idea reused on undirected graphs.
  • Union-Find — alternative connectivity tool (undirected only).

Concept Map

defines

maximal set where

contract each

always forms

enables

found by

found by

pass 1 records

earlier SCC finishes

pass 2 on

each DFS tree equals

runs in

runs in

Directed graph

Strongly Connected Component

u to v and v to u

Condensation

DAG no cycles

Topo order, longest path

Kosaraju two DFS

Tarjan one DFS

Finish times

later time

Reversed graph

O of V plus E

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, SCC ka matlab hai directed graph mein aise nodes ka group jahan har node se har doosre node tak ja sakte ho aur wapas bhi aa sakte ho. One-way roads waale shehron jaisa socho — agar ek club ke andar saare cities mein round-trip possible hai, toh wo ek SCC hai. SCC important kyun? Kyunki jab tum har SCC ko ek single node maan ke "shrink" karte ho, toh poora graph ek DAG ban jaata hai — saare cycles gaayab, aur DAG par kaam (topological order, longest path) bahut easy ho jaata hai.

Kosaraju ka funda simple hai: pehle normal DFS chalao aur har node ka finish time note karo (jab uske saare children khatam ho jaate hain). Phir saare edges ulta kar do (reverse graph), aur jis node ka finish time sabse zyada hai usse start karke DFS karo decreasing finish-time order mein. Har DFS tree exactly ek SCC dega. Yaad rakhna — ulta graph aur decreasing order, dono zaroori hain, warna answer galat aayega.

Tarjan smart hai — sirf ek DFS mein kaam ho jaata hai. Har node ko disc (discovery index) deta hai aur low track karta hai (sabse purana node jahan tak wapas pahunch sakte ho). Ek explicit stack rakhta hai with onStack flag. Jab kisi node par low[u] == disc[u] mile, samajh lo wo apne SCC ka leader hai — stack se us node tak sab pop kar do, wahi ek SCC hai. Important rule: tree edge ke liye low[v] lo, lekin back/cross edge ke liye sirf disc[v] (aur tabhi jab onStack[v] true ho) — warna alag SCCs galti se merge ho jaayenge.

Dono O(V+E) hain. Exam/interview mein: agar one-pass aur low-link concept chahiye toh Tarjan, agar simple "DFS + reverse" yaad rakhna easy lage toh Kosaraju. Donon ki backbone DFS hi hai.

Go deeper — visual, from zero

Test yourself — Graphs

Connections