割点模板
0 likes, on 2019-09-13 17:00:46, in 未分类
#include<iostream>
#include<cstdio>
#include<stdio.h>
using namespace std;
int root,tot=0;
int first[201001],to[201001],next[201001];
int tt=0,ans=0;
int dfn[30001],low[30001];
bool vis[30001];
void add(int x,int y)//建表
{
tot++;
next[tot]=first[x];
first[x]=tot;
to[tot]=y;
}
void tarjan(int x)
{
int flag=0;
low[x]=dfn[x]=++tt;//开始的时候给每一个点打上一个时间戳
for(int i=first[x];i>0;i=next[i])
{
int y=to[i];
if(!dfn[y])//
{
tarjan(y);
low[x]=min(low[x],low[y]);//是比较DFS树上的边
if(low[y]>dfn[x])
{
flag++;
if(flag>1||root!=x)
{
if(vis[x]==0)
{
vis[x]==1;
ans++;
}
}
}
}
else low[x]=min(low[x],dfn[y]);//所有的点都被遍历了以后才会通过一条非书上的点走到这个点(这条边不是树上的)
// 和y这个点的dfn比较,如果dfn比这个值得low小,说明y这个点的low更小
}
}
int main()
{
int n,m,x,y;
cin>>n>>m;
for(int i=1;i<=m;i++)//建立一张图
{
cin>>x>>y;
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++)// 这是在保证要每一一个点都是有时间戳的
{
if(!dfn[i])
{
root=i;
tarjan(i);
}
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)
{
if(vis[i])cout<<i<<" ";
}
}
本文介绍了一种用于检测图中割点的算法实现。通过Tarjan算法遍历图并标记割点,即移除该点后图将变得不连通的节点。文章提供了完整的C++代码示例,并解释了关键步骤。
935





