Tarjan算法的改装

     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)是桥。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值