强连通性Tarjan算法和LCA

其实tarjan算法提出的思想就是DFS深度优先遍历,在遍历的过程中记录某些变量的值,来解决相关问题,下面两个经典的问题都能通过tarjan的思想去解决。在此表达对Robert Tarjan的崇高敬意。

连通

基础思想

就是通过DFS,在深度优先遍历的过程中,记录每个节点上对应的值,在编程中我们需要记录的每个节点的值有DFN(访问的次序),inStack(是否在栈中,引入的栈是做什么的,下面会演示),LOW(记录该节点可以追溯到的节点的时间戳),然后通过比较DFN和LOW的值去判断该节点是否能构成连通分量。

伪代码

void varjan(节点 t)//深搜
    对于与节点t相连的每个节点i
        如果i没有访问过,则
            varjan(i)//继续深搜
            LOW[t]=min(LOW[i],LOW[t]);//回朔到该点时;
        如果i访问过,并且i在栈中,那么
            LOW[t]=min(LOW[t],DFN[i]);

    if LOW[t]==DFN[t]
        输出栈中位于t前面的所有的节点为一个连通风量。

下面我们通过题目去讲解tarjan的思想,看一下是如何判断一个图是否是连通图的。
这是一个老图,了解强连通的应该可以看出来,该图有三个连通分量分别为{1,2,3,4},{5},{6}

这里写图片描述

那么如何利用程序去寻找该图中有那些连通分量呢?

1.我们以节点1为开始节点,去深度优先别的遍历每一个节点。

这里写图片描述

2.到节点6的时候,我们发现6没有子节点,于是判断其DFN与LOW是否相等,相等则弹出栈中6以上的所有节点为一个连通分量,可知只有6一个。

这里写图片描述

3.回溯到5,发现与节点6一样,找不到未访问的子节点。于是栈中弹出5然后继续回溯。

这里写图片描述

4.然后继续从节点2开始深度优先访问4,则4的DFN和LOW即为5;当访问4->1路线时,发现1节点已经访问过了,而且存在栈中,所以使得LOW[4]=min{DFN1,LOW[4]}=1;
这里写图片描述

5.节点4的子节点都访问完了,判断DFN[4]不等于LOW[4],所以继续回朔到2,LOW[2]=min{LOW[4],LOW[2]}=1。又因为节点2的所有子节点也访问完了,所以判断DFN[2]不等于LOW[2],继续回朔,访问节点3。过程是一样的,就不分析了。下面结合代码去更好的理解。

代码实现

//============================================================================
// Name        : Tarjan.cpp
// Author      : SELOUS
// Version     :
// Copy
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值