Strong Components in Linear Time

Explore the different techniques used to implement strong components in linear time efficiently.

Lemma for computing strong components

In fact, there are several algorithms to compute strong components in O(V+E)O(V + E) time, all of which rely on the following observation.

Lemma 1: Fix a depth-first traversal of any directed graph GG. Each strong component CC of GG contains exactly one node that does not have a parent in CC. (Either this node has a parent in another strong component, or it has no parent.)

Proof: Let CC be an arbitrary strong component of GG. Consider any path from one vertex vCv ∈ C to another vertex wCw ∈ C. Every vertex on this path can reach ww, and thus can reach every vertex in CC; symmetrically, every node on this path can be reached by vv, and thus can be reached by every vertex in CC. We conclude that every vertex on this path is also in CC.

Let vv be the vertex in CC with the earliest starting time. If vv has a parent, then parent(v)parent(v) starts before vv, and thus can’t be in CC.

Now, let ww be another vertex in CC. Just before DFS(v)DFS(v) is called, every vertex in CC is new, so there is a path of new vertices from vv to ww. The Lemma from the lesson “Preorder and Postorder” now implies that ww is a descendant of vv in the depth-first forest. Every vertex on the path of tree edges vv to ww lies in CC; in particular, parent(w)Cparent(w) ∈ C.

Conclusion of Lemma

The previous lemma implies that each strong component of a directed graph GG defines a connected subtree of any depth-first forest of GG. In particular, for any strong component CC, the vertex in CC with the earliest starting time is the lowest common ancestor of all vertices in CC; we call this vertex the root of CC.

Create a free account to access the full course.

By signing up, you agree to Educative's Terms of Service and Privacy Policy