Tarjan 算法的伪代码实现 及 求割点的思路浅谈

来源:互联网 发布:最优化方法王开荣pdf 编辑:程序博客网 时间:2024/05/03 09:50

Tarjan算法的伪代码实现 及 求割点的思路浅谈

    

   1Tarjan算法求强连通分量

 

   设置DFN[], LOW[],数组进行搜索。DFN[S],代表S的时间戳, 也就是S的地位。而LOW[S]代表S能追寻的先祖节点的时间戳,把未放入过的节点放入栈中, 如果搜到底回溯时发现DFN[S] = LOW[S], 那么便把栈中包括SS之后的节点弹出, 这些节点便是一个连通分量。

 

   Tarjan算法的伪代码实现

 

   Void tarjan(int S)

   {

          Stack.push(S); // S放入栈中。

          Vis[S] = 1;// 表示S节点在栈中。

          DFN[S] = LOW[S] = ++FLAG // 初始化时间戳及先祖地位。

          For( T 属于 Sson) // 遍历所有S的子节点。

          If(vis[T] == 0) // 如果 不在栈中

          {

              Tarjan(T);  //继续向下搜索。

              LOW[S] = MIN(LOW[S], LOW[T]). //更新S节点的先祖地位。

          }

          Else  if(vis[T] == 1) //S节点 正在栈中。

          {

               LOW[S] = MIN(LOW[S], DFN[T]). // 更新S节点的先祖地位。

          }

          If(LOW[S] == DNF[S]) // 如果 S节点的先祖地位就是他自己 那么他就是一个强连通分量的ROOT。                                            

          {

               DO{

               Pop T //  弹出T

               Vis[T] = 2; // 表示T节点已经进入过并弹出

               T = stack.top; //更新T

               }While(S != T) // 一直弹到本强连通分量的ROOT为止。 弹出的节点便是一个强连通分量。

          }

 }

 

  2Tarjan算法求割点

 

  1. 如果S这个节点是根节点, 并且他有两个或两个以上的子节点, 那么S节点必然是割点。

   2, 如果S节点不是根节点, 那么我们可以设置DFN[], LOW[],数组进行搜索。 DFN[S],代表S的时间戳, 也就是S的地位。而LOW[S]代表S能追寻的先祖节点的时间戳, 如果用Tarjan算法实现, 发现关于S节点存在S节点的子节点TTLOW[T] >= DFN[S], 也就是说T的最高先祖地位不超过S节点, 那么S节点断了, TT之后的节点便会与之前的图断开, 所以S便为割点。


注:这些都是我自己的想法,不一定精准, 如有错误, 请各位大牛指出, 谢谢。

0 0
原创粉丝点击