Definition · Strongly connected componentA strongly connected component of a digraph is a maximal set of vertices in which every vertex reaches every other. Maximal matters: a single vertex is always mutually reachable with itself, so without maximality every vertex would be its own component and the definition would say nothing.
The classes of the relation are those maximal sets, so nothing further has to be checked: partition and maximality come together. The brute-force method is the definition made mechanical — compute reachability from every vertex, then group u with v when each appears in the other's set — and that is what the lab runs beside the fast method.
The algorithm, in two passes
- Run a depth-first walk on the digraph, restarting as needed, and record the finish time of every vertex.
- Reverse every arc.
- Walk the reversed digraph, starting each new tree at the undiscovered vertex with the largest finish time from the first pass.
- The vertex set of each tree in the second pass is one component.
Nothing about step 3 is arbitrary and everything about it is fragile. Taking the vertices in increasing finish order, or walking the original arcs in the second pass, both produce something — a partition of the vertices — and neither produces the components. The lab's independent check is the only thing on the page that can tell the difference.
Theorem · The last vertex to finish is in a source componentLet v have the largest finish time of a depth-first walk on a digraph. Then the component containing v has in-degree 0 in the condensation: no arc enters it from another component.
Suppose an arc ran from a component B into the component A of v, and let b be its tail. Since the condensation is acyclic, no path returns from A to B.
Consider which of A and B the walk enters first. If it enters B first, then from inside b it can reach A along that arc, so every vertex of A is discovered inside the call at b and finishes before it, making f[b] > f[v]. If it enters A first, then it cannot reach B at all from A, so B is untouched while A finishes, and b is discovered afterwards, again giving f[b] > f[v].
Either way something finishes later than v, contradicting the choice of v. So no such arc exists.
□
That theorem is the whole design. Standing in a source component and following the reversed arcs, everything reachable is inside the component: the reversed arcs that would take you out of it are the forward arcs that came in, and there are none. So the second pass's first tree is exactly one component. Remove it and the remaining condensation still has the same property, so the argument repeats.
Example · Seven vertices, three componentsThe lab opens on 1>2, 2>3, 3>1, 3>4, 4>5, 5>6, 6>4, 5>7. The first walk finishes the vertices in the order that makes the decreasing list 1 2 3 4 5 7 6. The second pass, on the reversed arcs, produces the components {1, 2, 3}, {4, 5, 6} and {7}. The condensation has three points and two arcs, in a line, and is acyclic. Mutual reachability computed from the definition returns the same three sets, and the panel prints both partitions.
Two things in that example are easy to misread. The vertex 7 is its own component not because it is isolated — 5 points at it — but because nothing comes back from it. And the decreasing finish list puts 7 before 6 even though 6 is lower-numbered, because the walk reached 6 first from 5 and closed it before it ever opened 7.
The cases at the two ends
A single cycle through every vertex is one component: on 1>2, 2>3, 3>4, 4>1 the lab reports one component of four vertices, and a condensation that is a single point with no arcs. An acyclic digraph is the other extreme: on 1>2, 2>3, 1>3, 3>4 every vertex is its own component, there are four of them, and the condensation is the graph itself. Those are the two cases where the second pass has the least to do, and running them is the fastest way to convince yourself the algorithm is not doing something else.
The counts, beside the bound. On the opening graph the second pass reports 7 vertex visits and 8 arc reads; on the four-vertex cycle, 4 and 4; on the acyclic preset, 4 and 4. Each is V and E for that graph. The bound is that the whole algorithm is Θ(V + E), and it is two walks plus a reversal: the reversal itself is one pass over the arcs, and neither walk visits a vertex twice. What the measurement cannot show is that no input makes it worse, and that is what the argument is for.