无向图割点的定义:在无向图中,割点(cut vertex)是指如果将该顶点及其关联的边从图中移除后,原本连通的图会被分成两个或更多个不连通的子图,则该顶点被称为割点。
无向图割点的判断:
在无向图中若x--y,且x不是根节点且y是x的子节点,若low[y]>dfn[x]则称x为割点
如果x是根则需要两个或以上根节点的low【子节点】>dfn【x】。
代码实现:
#include<iostream>
#include<cstring>
#define maxn 1005
using namespace std;
int head[maxn],cnt,root,dfn[maxn],low[maxn],num;
struct node{
int next,to;
}e[maxn<<1];//无向图----双向边
void add(int u,int v){
e[cnt].next=head[u];
e[cnt].to=v;
head[u]=cnt++;
}
void tarjan(int u,int fa){
dfn[u]=low[u]=++num;
int count=0;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]){
count++;
if(count>=2||u!=root)
cout<<u<<"是割点\n";
}
}
else{
low[u]=min(low[u],dfn[v]);
}
}
}
int main(){
int n,m;
cin>>n>>m;
int u,v;
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
cnt=0,num=0;
for(int i=0;i<m;i++){
cin>>u>>v;
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i]){
root=i;
tarjan(i,0);
}
}
return 0;
}
/*
测试用例:
5 4
1 2
2 3
2 5
3 1
*/