Tarjan算法的改装

来源:互联网 发布:软件测试工具大全 编辑:程序博客网 时间:2024/04/27 21:11

     Tarjan算法是用来解决强连通分量问题的常用算法,算法是基于深度优先搜索的架构,在深度优先搜索的过程中,迭代地求出各个节点U的标值lowlink(U),其中:lowlink(U)=min(dfn(U),dfn(W))。在这里,W是从U和U的后代点出发用一条后向弧和横叉弧所能达到的同一个强连通分支的节点,dfn(U)是深度优先遍历中节点U的遍历序号。

     这样子,我们发现,在求解lowlink(U)时,我们必须考虑U的邻接节点W与U是否是与U在同一个连通分支中,这也是算法的难点。笔者提出了一种比较直观的判断W是否与U在同一个连通分支的算法,该算法在效率上可能比经典算法略逊,但易于理解。下面给出POJ2186的主要代码:

      在这里,数组dfn保存节点的dfn值,数组low保存节点的lowlink值,数组con保存节点所属的连通分量的序号,数组out标记各个节点是否存在出边连接其他连通分量(由于本题只需要考虑连通分量的出度,所以没有必要把整个桥保存下来,只需要保存桥的起点)。

       对于当前遍历的节点U,以及它的邻接节点W,我们分两种情况考虑:

       如果dfn[W]=0(初值),也即W还没有遍历到:

             那么:我们遍历W,W遍历完毕以后:

                      如果low[W]>dfn[U]:说明从W出发不可能到达U,U和W不在同一个连通分支中,(U,W)是桥;

                      否则:U和W在同一个连通分量中,于是更新low[U]:=min(low[U],low[W]);

        如果dfn[W]!=0(初值),也即W在遍历U之前已经遍历到了:

              此时,还需分两种情况讨论:

                      如果con[W]=0(初值):说明W还没有被划分到一个连通分量中,那么U与W应该处于同一个连通分量,(U,W)是后向边

                                                       或者同一个连通分量的横叉边,于是更新low[U]:=min(low[U],low[W]);

                      如果con[W]!=0:说明W已经被划分到同一个连通分支,U和W不在同一个连通分支中,(U,W)是桥。

 

原创粉丝点击