Link
P3388 【模板】割点(割顶)
code
#include<bits/stdc++.h>
using namespace std;
const int maxn=20005,maxe=200005;
int N,M;
int cnt=1,lnk[maxn],nxt[maxe],son[maxe];
int dfn[maxn],low[maxn],num,cut[maxn],root,Ans[maxn];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
void tarjan(int x){
dfn[x]=low[x]=++num;
int flg=0;
for(int j=lnk[x];j;j=nxt[j]){
if(!dfn[son[j]]){
tarjan(son[j]);
low[x]=min(low[x],low[son[j]]);
if(low[son[j]]>=dfn[x]){
flg++;
if(x!=root||flg>1)cut[x]=1;
}
}
else low[x]=min(low[x],dfn[son[j]]);
}
return ;
}
inline void add_e(int x,int y){son[++cnt]=y;nxt[cnt]=lnk[x];lnk[x]=cnt;}
int main(){
freopen("P3388.in","r",stdin);
freopen("P3388.out","w",stdout);
N=read();M=read();
for(int i=1;i<=M;i++){
int x=read(),y=read();
add_e(x,y);add_e(y,x);
}
for(int i=1;i<=N;i++)
if(!dfn[i]){root=i;tarjan(i);}
for(int i=1;i<=N;i++)
if(cut[i])Ans[++Ans[0]]=i;
printf("%d
",Ans[0]);
for(int i=1;i<=Ans[0];i++)
printf("%d ",Ans[i]);
return 0;
}