1

By now, I have used the following algorithm for finding the strongly connected components of a graph.

  1. 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;

  2. compute the transpose GT of G;

  3. 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];

  4. 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.

LAP
  • 122
  • 1
  • 4
  • 14

2 Answers2

2

I found this on the Wikipedia page for Strongly connected component:

Kosaraju's algorithm, Tarjan's algorithm and the path-based strong component algorithm all efficiently compute the strongly connected components of a directed graph, but Tarjan's and the path-based algorithm are favoured in practice since they require only one depth-first search rather than two.

I think this quite answers your question :)

alestanis
  • 21,519
  • 4
  • 48
  • 67
2

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.

user1071840
  • 3,522
  • 9
  • 48
  • 74
  • 1071840 can u give me the link from where u read this material. I would like to go through complete topic as it has said some new things here. – LAP Oct 24 '12 at 04:28
  • http://sist.sysu.edu.cn/~isslxm/DSA/textbook/Skiena.-.TheAlgorithmDesignManual.pdf – user1071840 Oct 25 '12 at 05:33