学习笔记——图的联通性问题
割点与割边
定义
连通分量:在一张无向图中的极大连通子图即为该图的连通分量。
割点:去掉这个点后,这张无向图的连通分量数量增加,则这个点称为这个图的割点。
割边:去掉这条边后,这张无向图的连通分量数量增加,则这条边称为这个图的割边。
求割点
主要思路
以下提到的有关树的内容,全部指的是对连通分量做 DFS 得到的 DFS 生成树上的内容。
我们对一个连通分量做一次 DFS,可以得到一棵搜索树。这里引入两个定理:
-
如果这棵 DFS 生成树的根节点至少有两个儿子节点,那么这个根节点是割点。
-
这棵 DFS 生成树中的非根节点的一个儿子节点不能不通过它们之间的连边回到这个点的祖先,那么这个点就是割点。
先看定理
这个很好理解,如果这个根节点不是割点,说明根节点只有一个儿子,因为其他点都可以在不经过根节点的情况下两两到达。看图:
图中黑色边为以
否则将这个节点删掉,一定会使连通分量的数量增加,因为有节点必须通过根节点才能到达别的节点。如图:
、
黑色边是以
我们再看定理
如果删掉这个点,连通分量数量变多,说明有点不再与其他点连通,即没有返祖边连回这个点的祖先。否则一定可以通过这条返祖边连回这个点的祖先,那么连通分量数量也不会增加。
在这个图中,搜索树以
可以看到,连通分量数量并没有增加。因为节点
那么要如何实现呢?我们可以在 dfs 时记录一个点的
那么如何更新
-
在遍历完
后回溯时,用 更新 。 -
如果
是返祖边,用 更新 。
那么判断割点也很好判断了,根据定理
举个例子:
对于上图,我们从
遍历节点
遍历节点
遍历节点
遍历节点
遍历节点
发现节点
回溯至节点
回溯至节点
回溯至节点
回溯至节点
遍历节点
遍历节点
遍历节点
发现节点
回溯至节点
回溯至节点
回溯至节点
由于根节点
所以这张图上的割点为
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,m,dfn[maxn],low[maxn],f[maxn],cnt;
vector<int> G[maxn];
void dfs(int cur,int u,int fa){
dfn[u]=low[u]=++cnt;
int sum=0;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(!dfn[v]){
sum++;
dfs(cur,v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]&&u!=cur){
f[u]=1;
}
}
else if(dfn[v]<dfn[u]&&v!=fa){
low[u]=min(low[u],dfn[v]);
}
}
if(u==cur&&sum>=2){
f[cur]=1;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
dfs(i,i,-1);
}
}
int ans=0;
for(int i=1;i<=n;i++){
if(f[i]) ans++;
}
cout<<ans<<endl;
for(int i=1;i<=n;i++){
if(f[i]) cout<<i<<" ";
}
return 0;
}
求割边
求割边,只要将求割点的条件从
为什么?
考虑何时
当从
图中节点
但是我们注意到
双连通分量
定义
点双连通分量:如果一个连通分量中不存在割点,则这个连通分量称为点双连通分量。
边双连通分量:如果一个连通分量中不存在割边,则这个连通分量称为边双连通分量。
求点双连通分量
问题:在一张无向图
这里有一个性质:割点会把一个连通分量分为若干个点双。
所以我们在求解割点的时候,使用栈来记录已经遍历过的边。当我们找到割点的时候,我们已经完成了对一个点双的遍历,所以此时栈中的元素就是一个点双。
为什么放入栈中的不是点,是边?
因为一条边只属于一个点双,而一个点可以属于多个点双,当这个点被弹出,就意味着这个点不能属于其他点双,所以存点会错。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】