luogu 3388 【模板】割点(割顶)
点双。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #define ll long long 10 #define inf 2139062143 11 #define MAXN 100100 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,m,res,stp,cnt,fst[MAXN],to[MAXN<<2],nxt[MAXN<<2],dfn[MAXN],low[MAXN],ans[MAXN]; 21 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 22 void tarjan(int x,int anc) 23 { 24 dfn[x]=low[x]=++stp;int rts=0; 25 for(int i=fst[x];i;i=nxt[i]) 26 { 27 if(!dfn[to[i]]) 28 { 29 tarjan(to[i],anc); 30 low[x]=min(low[x],low[to[i]]); 31 if(low[to[i]]>=dfn[x]&&x!=anc) ans[x]=1; 32 if(x==anc) rts++; 33 } 34 low[x]=min(low[x],dfn[to[i]]); 35 } 36 if(x==anc&&rts>1) ans[anc]=1; 37 } 38 int main() 39 { 40 n=read(),m=read();int a,b; 41 for(int i=1;i<=m;i++) {a=read(),b=read();add(a,b);add(b,a);} 42 for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i); 43 for(int i=1;i<=n;i++) if(ans[i]) res++;printf("%d\n",res); 44 for(int i=1;i<=n;i++) if(ans[i]) printf("%d ",i); 45 }