tarjan算法总结

89 篇文章 0 订阅
72 篇文章 0 订阅

tarjan学了老是忘,还容易把边双点双强连通分量搞混,这里写个总结。

定义dfn(x)为x点dfs序,low(x)为该点能通过非树边返回的深度最小祖先的dfn。

一、无向图tarjan:

1.求low(x)

首先将low(x)初始化为dfn(x),对于连着x的边(x,y),若x为y父亲,则先dfs(y),low(x)=min(low(x),low(y)),不然说明为非树边,low(x)=min(low(x),dfn(y))

2.割点和桥

定义桥为删除掉图会分裂成两个及以上子图的边,割点为删除掉图会分裂为两个以上子图的点。

若一条x到子节点y的边是桥,则要满足dfn(x)<low(y),所以dfs判一下即可,要注意与平时dfs(x)传入fa(x)不同这里要传入fa(x)到x的边标号以防重边情况。

割点情况类似,若x是割点,则要存在一个y,使得dfn(x)<=low(y),这里可以不用判断重边情况(最好还是判反正没多大区别),需要注意根是割点的条件较特殊是有两个及以上子节点。

3.点双边双

点双图是一个无向图,其中不存在割点。点双连通分量指原图一个极大点双连通子图(即不存在包含它更大点双子图)。

边双图是一个无向图,其中不存在桥。边双连通分量指原图一个极大边双连通子图(即不存在包含它更大边双子图)。

有一些没啥用的定理:

1.点双图至少满足以下两条件之一:顶点数不超过2;任意两点至少包含在一个简单环(不自交环)中。

2.一张图是边双图当且仅当任意边都包含在至少一个简单环中。

求边双:将桥边删除,每个连通块都是一个边双。而将每个边双看成一个点建新图即可完成边双缩点。

求点双:首先对于孤立点(没有连边的)直接自己作为点双,其余的就在tarjan时维护一个栈,一个点第一次访问时加入栈,当出现dfn(x)<=low(y),从栈顶不断弹,弹出y为止,所有弹出的和x构成割点。之后缩点则将每个割点和包含它的点双连边构成森林。

二、有向图tarjan

一张有向图,若其中任意两个点x,y都既存在x到y路径也存在y到x路径,则其为强连通图,类比点双边双分量可以定义强连通分量。

求强连通分量:维护一个栈记录当前点祖先点集合,然后计算low(x)时与求割点桥差不多,就是一个点要判断是当前点祖先要看它是否在栈中。最后在x点回溯前判断是否有low(x)==dfn(x),如果有则将栈弹到x出栈为止,所有出栈的构成一个强连通分量,缩点则与边双类似。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值