Algorithm for strongly connected components -Tarjan

Long time did not write a blog ( blame too much work, I'm definitely not playing too Hey a )

So today is a tall write on something: strongly connected

First, some definitions related strongly connected // degrees from Mother

1. FIG strongly connected (Strongly Connected Graph) is meant a directed graph G, if for each pair vi, vj, vi ≠ vj, from vi to vj vi to vj and from there the path G is called strong FIG communication.

2. strongly connected subgraph to FIG great called strongly connected components (strongly connected components).

Of course, look at the definition is certainly not read, so I give chestnuts explain

We have the following diagram, for example, this is a particularly strong graph with the classic, three framed up three places on are strongly connected component

We look at DFS, a departure from, we traverse from right to left, so the path is 1--> 3 -> 5 -> 6 to 6, we found no way out, went back to 5, and 6 can not reach any point, it is a strongly connected component alone. Similarly, 5 is a strongly connected components. And 1--> 3 -> 4 -> 1--> 2, we can reach each other, so this is a strongly connected component.

 

Tarjan algorithm

Next, it is a strong communication in a common algorithm.

Tarjan algorithm is based on depth-first search algorithm of FIG., Each strongly connected component of a subtree of the search tree. When searching, the current node in the search tree unprocessed added a stack, the stack can be determined whether a stack node is strongly connected components when backtracking.

Defined DFN (u) is the order of the node number (time stamp) u search, Low (u) for the u or u sub-tree can be traced back to the sequence number of the earliest stack node.

When DFN (u) = when the Low (u), u is a root in search of all the sub-tree node is a strongly connected component.

Then demonstrate what algorithm:

从1开始DFS,把遍历到的节点加入栈中。搜索到节点u=6时,DFN[6]=LOW[6],找到了一个强连通分量。退栈到u=v为止,{6}为一个强连通分量。

 返回到5,发现DFN[5]=LOW[5],退栈后{5}为一个强连通分量。

 继续回到1,最后访问2。访问边(2,4),4还在栈中,所以LOW[2]=DFN[4]=5。返回1后,发现DFN[1]=LOW[1],把栈中节点全部取出,组成一个连通分量{1,3,4,2}。

 

所以,三个强连通分量全部都找出来了。

模板如下:

 1 void Tarjan(int u){
 2     dfn[u]=low[u]=++num;
 3     st[++top]=u;
 4     for (int i=fir[u]; i; i=nex[i]){
 5         int v=to[i];
 6         if (!dfn[v]){
 7             Tarjan(v);
 8             low[u]=min(low[u],low[v]);
 9         }
10         else if (!co[v])
11             low[u]=min(low[u],dfn[v]);
12     }
13     if (low[u] == dfn[u]){
14         co[u]=++col;
15         while (st[top]!=u){
16             co[st[top]]=col;
17             --top;
18         }
19         --top;
20     }
21 }

 

Guess you like

Origin www.cnblogs.com/Alan-Anders/p/11225168.html