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.
low[i] = i;
scc[i] = -1;
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.
int edge_classification(int x, int y)
{
if (parent[y] == x) return(TREE);
if (discovered[y] && !processed[y]) return(BACK);
if (processed[y] && (entry_time[y]>entry_time[x])) return(FORWARD);
if (processed[y] && (entry_time[y]<entry_time[x])) return(CROSS);
printf("Warning: unclassified edge (%d,%d)\n",x,y);
}
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;
}
if (class == CROSS)
{
if (scc[y] == -1) /* component not yet assigned */
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).
process_vertex_early(int v)
{
push(&active,v);
}
After DFS for a vertex is complete (DFS for it's neighbors would have been completed too), check the lowest reachable vertex for it:
if (low[v] == v)
{ /* edge (parent[v],v) cuts off scc */
pop_component(v);
}
if (entry_time[low[v]] < entry_time[low[parent[v]]])
low[parent[v]] = low[v];
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.