By now, I have used the following algorithm for finding the strongly connected components of a graph.
-
call DFS(G) to compute the finishing time f[v] for every vertex v, sort the vertices of G in decreasing order of their finishing time;
-
compute the transpose GT of G;
-
Perform another DFS on G, this time in the main for-loop we go through the vertices of G
in the decreasing order of f[v]; -
output the vertices of each tree in the DFS forest (formed by the second DFS) as a separate
strongly connected component.
.
But I was wondering if it is possible to find all the strongly connected components in only one DFS.
Any help in this regard would be highly appreciated.
Check out, Algorithm Design Manual by Steven Skiena. It calculates SCC in one DFS. It’s based on the concept of oldest reachable vertex.
Initialize each vertex’s reachable vertex and SCComponent# to itself in the beginning.
Do a DFS on the digraph, you are interested only in back edges and cross edges because these two edges will tell you if you’ve encountered a back edge and entering 1 component from another.
So when you encounter these edges, you set reachable vertex[] recursively, based on the entry times.
if (class == BACK) {
if (entry_time[y] < entry_time[ low[x] ] )
low[x] = y;
}
A new strongly connected component is found whenever the lowest reachable vertex from vertex ‘v’ is itself (loop can say, a->b->c->a, lowest reachable vertex of a is a).
After DFS for a vertex is complete (DFS for it’s neighbors would have been completed too), check the lowest reachable vertex for it:
pop_component(…) just pops from the stack until this component is found. If a->b->c->a is scanned the stack will have a(bottom)->b->c(top).. pop until vertex ‘a’ is seen. You get an SCC for ‘a’..and similarly you get all connected components in one DFS.