tarjan算法

本文介绍了Tarjan算法在有向图中的应用,包括求解强连通分量和识别割点。通过手动模拟算法过程,解释了树边、返祖边和横插边的区别,并提供了无向图中割点的判断方法。通过对图的深度优先搜索,理解dfn和low值的含义,以此来确定强连通分量和割点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

咳咳咳,之前对tarjan半生不熟的,还转载了百度百科的tarjan,现在想起来真是惭愧啊。
为了弥补在图论方面的弱项,最新学习了tarjan,边学边分享问题和想法吧,这样可能更好理解一些。
首先,有很多专业术语。
1.强连通分量
假设我们有一个子图。

这个子图的任意两点都可以互相到达,则我们称这个子图为一个强连通分量
2.DAG
有向无环图
这里写图片描述
3.边双联通分量
一个无向图(这很重要)中,若是任意删除一条边,都不改变图的连通性,则称这个图为双联通图,同理,在某一个子图里,若是任意删除一条边,都不改变这个子图的连通性,则称这个子图为一个双联通分量。
4.点双联通分量
同上,把边换成点。
PS:
一个双联通分量中,从一个点到另一个点的路径必定至少有两条,且不经过相同的边(点)
5.割边(桥)
在一个连通图中,若删除某一条边使得原图变成两个联通快,则称这条边为割边,也叫桥。
6.割点
同5,把边换成点。

知道这些就差不多了。
我们知道,图分有向图和无向图,对于两种图,tarjan的用法以及求的东西也不一样。
定义
dfn[i]表示第i个点的dfs序,也就是第几个被访问到的。
low[i]表示第i个点以及它的子树中最小的dfn
d这是一个栈,用来存子树。
有向图
我学的时候,讲师说只用于缩强连通分量,也就是缩点。
但是它还可以求强连通分量的个数,大小(怀疑是不是太显然讲师不屑于讲)
在讲如何做之前,我们知道有向图有三种边(讲师讲的)
1.树边
2.返祖边(返回祖先的边)
3.横插边(横插到另一个子树的边)
这里写图片描述
在这个图中,a,b,c,d,f是树边
e是横插边
h是返祖边
返租边会用到,横插边不理它。
就着上边的图,手动模拟tarjan怎么算强连通分量的。
首先在1,dfn[1]=low[1]=1,d[1]
然后去到2,dfn[2]=low[2]=2,d[1,2]
去到4,dfn[4]=low[4]=3,d[1,2,4]
没地方去了(完全没地方可以去)
没地方去了就是dfn[i]=low[i]了
它自己就是最小的,是起始点。
这时4就是一个强连通分量
然后把4以及它的子树(如果有)都退栈
怎么退栈?
我们深搜,搜完后父亲一定在儿子前面,
所以只要退到4都退栈就行了,d[1,2]
这时回到2,low[4]>low[2],所以不理
去到5,dfn[5]=low[5]=4,d[1,2,5]
这时有一条边连到3,我们去到3
疑问:按照很多博客的说法,横插边是不理的,为什么这里走了。
思考:这图画错了。
正确的图(并不完整,等会给完整的):
这里写图片描述
画的有些恶心。。。,但是大致可以看出来。
好我们接着模拟,dfn[3]=low[3]=5,d[1,2,5,3]
去到6,dfn[6]=low[6]=6,d[1,2,5,3,6]
这时有一条边连到1,这时一条返祖边,我们不走,但是更新low值
low[6]>dfn[1],所以将low[6]更新为dfn[1]。
对于返祖边,假设从

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值