Strong connectivity. Strong connectivity is an equivalence relation on the set of vertices:
Reflexive: Every vertex v is strongly connected to itself.
Symmetric: If v is strongly connected to w, then w is strongly connected to v.
Transitive: If v is strongly connected to w and w is strongly connected to x, then v is also strongly connected to x.
Strong connectivity partitions the vertices into equivalence classes, which we refer to as strong components for short. We seek to implement the following API:
API for strong components
Remarkably, KosarajuSharirSCC.java implements the API with just a few lines of code added to CC.java, as follows:
Given a digraph G, use DepthFirstOrder.java to compute the reverse postorder of its reverse, GR.
Run standard DFS on G, but consider the unmarked vertices in the order just computed instead of the standard numerical order.
All vertices reached on a call to the recursive dfs() from the constructor are in a strong component (!), so identify them as in CC.
Proposition. The Kosaraju-Sharir algorithm uses preprocessing time and space proportional to V + E to support constant-time strong connectivity queries in a digraph.
Transitive closure. The transitive closure of a digraph G is another digraph with the same set of vertices, but with an edge from v to w if and only if w is reachable from v in G.