题目链接
用tarjan的裸题,对于一个点,设其子节点中一个节点y,当且仅当dfn[x]≤low[y]时为割点,特别的,对于根节点,要有两个y满足要求。
时间:100ms。
#include<bits/stdc++.h>
using namespace std;
int ans=0,cut[1000010],hed[1000010],nxt[2000010],ver[1000010],dfn[1000010],low[1000010],n,m,tot=0,num,root;
void add(int x,int y){
ver[++tot]=y,nxt[tot]=hed[x],hed[x]=tot;
}
void tarjan(int x,int fa){
dfn[x]=low[x]=++num;
int flag=0;
for(int i=hed[x];i;i=nxt[i]){
int y=ver[i];
if(!dfn[y]){
tarjan(y,fa);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x]&&x!=fa)
cut[x]=1;
if(x==fa) flag++;
}
low[x]=min(low[x],dfn[y]);
}
if(x==fa&&flag>=2)
cut[fa]=1;
}
int main(){
scanf("%d%d",&n,&m);;
for(int i=1,x,y;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
for(int i=1;i<=n;i++)if(!dfn[i])
tarjan(i,i);
for(int i=1;i<=n;i++)
if(cut[i])
ans++;
printf("%d\n",ans);
for(int i=1;i<=n;i++)
if(cut[i])
printf("%d ",i);
return 0;
}