洛谷P3388
注意:记得tarjan的打法
注意割点的判断条件:子节点个数>2并且为根节点
当它不为根节点时并且low[to]>dfn[u]
判断时是在子节点未被记录的时候
1 #include<bits/stdc++.h> 2 using namespace std; 3 inline int sc() 4 { int x=0,f=1;char ch=getchar(); 5 while(!isdigit(ch)){ if(ch==45)f=-1;ch=getchar();} 6 while(isdigit(ch)) { x=x*10+ch-48;ch=getchar();} 7 return x*f; 8 } 9 #define man 100010 10 int n,m; 11 /*edge*/ 12 int head[man<<2],num=0; 13 struct edge 14 { int next,to;}e[man<<2]; 15 inline void add(int from,int to) 16 { e[++num].next=head[from]; 17 e[num].to=to; 18 head[from]=num; 19 } 20 21 int dep=0,dfn[man],low[man],cnt=0; 22 bool vis[man],sta[man]; 23 inline void tarjan(int u,int fa) 24 { int son=0; 25 low[u]=dfn[u]=++dep; 26 for(int i=head[u];i;i=e[i].next) 27 { int to=e[i].to; 28 if(!dfn[to]) 29 { son++; 30 tarjan(to,u); 31 low[u]=min(low[u],low[to]); 32 if((fa==-1&&son>=2)||(fa!=-1&low[to]>=dfn[u])) 33 { if(sta[u]==0) cnt++;sta[u]=1;} 34 } 35 else if(to!=fa) 36 low[u]=min(low[u],dfn[to]); 37 } 38 } 39 int main() 40 { n=sc();m=sc(); 41 for(int i=1,x,y;i<=m;i++) 42 { x=sc(),y=sc(); 43 add(x,y);add(y,x); 44 } 45 for(int i=1;i<=n;i++) 46 if(!dfn[i]) tarjan(i,-1); 47 cout<<cnt<<endl; 48 for(int i=1;i<=n;i++) 49 if(sta[i]) cout<<i<<" "; 50 cout<<endl; 51 return 0; 52 } 53