简单易懂的 Tarjan求割点与桥 详解
一些简单的概念
连通分量:无向图G的极大连通子图称为G的连通分量
说人话:把无向图G分成几块,满足每一块内都是连通的,且几个块之间不连通,这些块就是G的连通分量
割点:无向连通图中,去掉一个顶点及和它相邻的所有边,图中的连通分量数增加,则该顶点称为割点。
说人话:如果去掉这个点,原来连通的某一块不连通了,那这个点就是割点
割边/桥:无向联通图中,去掉一条边,图中的连通分量数增加,则这条边称为割边或者桥
说人话:如果去掉这条边,这条边连着的两个点就不连通了,那这条边是割边/桥
比如下图:点1和点4为割点,边 1-4 为桥
那么我们如何求一张图的割点和桥呢?
Tarjan
(为了方便,以下先假设图连通)
割点
在一张图上跑dfs,由于访问过的点不会重复访问,显然把搜索过程中经过的所有边和点合起来会构成一棵树,这棵树被叫做搜索树,在这棵树上的边会被称作树边。
比如上一张图的搜索树如下:
如果一个点
比如在这棵树中,5、6在原图上不通过4不可能到达1、2、3三个点,所以4为割点
至于没有根节点的父节点,之后再额外做讨论
那么如何找到满足条件的点呢?这就要用到Tarjan了。
Tarjan定义了两个数组:
dfn[x]:表示在dfs过程中x是第几个被遍历到的,即dfs的时间戳。注意:如果dfn[x]>dfn[y],这说明y必然不在x的子树上
low[x]:表示x不经过父节点的情况下,所能到达的dfn最小的节点。(事实上并不保证dfn一定最小,但这样可以方便理解)
在搜索过程中:
low[x]初始化为dfn[x]。
对于x的父节点,我们跳过它即可
在搜索的过程中,对于x的子节点y,x可以直接通过y到达low[y],即low[x]=min(low[x],low[y])。
对于其他与x相连的点y,x到达low[y]的过程中不能保证不会经过x的父亲,所以我们只能让low[x]=min(low[x],dfn[y])。
最后是判断割点:
由于,在不经过非根节点x的情况下,如果x的孩子节点y能够到达某一不在x的子树上的节点,那么它必然能通过树上的边到达某一dfn值小于x的节点,也就是说必然满足low[y]<low[x]
反之,如果low[x]>=low[y],则y必然不能在不通过x的情况下到达其他点
也就是说,如果存在x的儿子节点y,使得low[x]>=low[y],则x为割点
当然,前提是这个点并非是根。如果是根的话,我们另外进行判断。
如果根节点的两棵子树通过某条边相连,那么我们必然在dfs的过程中必然能通过该边从一棵子树到另一棵子树,那两棵子树就变成一棵了。所以只要根节点有两棵或以上的子树,就说明两棵子树没有其他边相连,根节点即为割点
请注意:以上只是对于Tarjan的概述,只能方便理解,但仍然有不少漏洞,并非严谨证明。只不过足够我们AC了
桥
与割点几乎一致的思路。如果一条边是桥,那么我们必然无法在不通过这条边的情况下到达其他点——只不过我们这次还加了一个限制:由于不让通过那条边,我们现在连根节点都去不了
所以当节点x有子节点y满足low[y]>dfn[x],就说明不能不通过(x,y)到达其他点,就说明(x,y)为桥
上代码
vector<int> s[114514]; int de,cnt; int dfn[114514],low[114514],vis[114514]; int is_cut[114514],is_bri[114514]; void dfs(int x,int fa){ de++; low[x]=dfn[x]=de; vis[x]=1; for(int y:s[x]){ if(y==fa) continue; if(vis[y]==0){ dfs(y,x); low[x]=min(low[y],low[x]); if(!fa){ cnt++; if(cnt>=2) is_cut[x]=1; //对根进行特判 } else if(low[y]>=dfn[x]) is_cut[x]=1; if(low[y]>dfn[x]) is_bri[y]=1;//is_bri[i]代表i与其父亲的连边是否为桥 } else low[x]=min(low[x],dfn[y]); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具