#include<iostream>
#include<cstdio>
#include<set>
#include<vector>
using namespace std;
const int maxn=1e5+5;
vector<vector<int> >g(maxn);
int n;
bool visited[maxn];
int prenum[maxn],parent[maxn],lowest[maxn],timer;
void dfs(int current,int prev)
{
prenum[current]=lowest[current]=timer;
timer++;
visited[current]=true;
int next;
for(int i=0;i<g[current].size();i++){
next=g[current][i];
if(!visited[next]){
parent[next]=current;
dfs(next,current);
//结点next搜索完毕后立刻执行的处理
lowest[current]=min(lowest[current],lowest[next]);
}else if(next!=prev){
//边current-->next为back-edge时的处理
lowest[current]=min(lowest[current],prenum[next]);
}
}
}
void art_points()
{
for(int i=0;i<n;i++){
visited[i]=false;
}
timer=1;
//计算lowest
dfs(0,-1);
set<int>ap;
int np=0;
for(int i=1;i<n;i++){
int p=parent[i];
if(p==0){
np++;
}else if(prenum[p]<=lowest[i]){
ap.insert(p);
}
}
if(np>1){
ap.insert(0);
}
for(set<int>::iterator it=ap.begin();it!=ap.end();it++){
cout<<*it<<endl;
}
}
int main()
{
int m;
cin>>n>>m;
for(int i=0;i<m;i++){
int s,t;
cin>>s>>t;
g[s].push_back(t);
g[t].push_back(s);
}
art_points();
return 0;
}
关节点(割点)
最新推荐文章于 2023-03-25 20:15:17 发布