这是tarjan求割点的模板题,在此tarjan算法不在赘述,主要讲一些易错点。
首先这张图不一定是连通图,所以我们不能直接从1开始dfs
注意tarjan算法中的一些细节。
注意输出格式!!!
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 inline int read() { 8 int ret=0; 9 int op=1; 10 char c=getchar(); 11 while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();} 12 while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar(); 13 return ret*op; 14 } 15 struct node { 16 int next,to; 17 }a[100010<<1]; 18 int n,m,head[200010],num,tot,dfn[20010],low[20010],vis[20010],root; 19 void add(int from,int to) { 20 a[++num].next=head[from]; a[num].to=to; head[from]=num; 21 swap(from,to); 22 a[++num].next=head[from]; a[num].to=to; head[from]=num; 23 } 24 void tarjan(int u) { 25 dfn[u]=low[u]=++tot; 26 int sum=0; 27 for(int i=head[u];i;i=a[i].next) { 28 int v=a[i].to; 29 if(!dfn[v]) { 30 tarjan(v); 31 low[u]=min(low[v],low[u]); 32 if(low[v]>=dfn[u]) { 33 sum++; 34 if(u!=root||sum>1) vis[u]=1; 35 } 36 } 37 else low[u]=min(low[u],dfn[v]); 38 } 39 } 40 int main() { 41 n=read(); m=read(); 42 for(int i=1;i<=m;i++) add(read(),read()); 43 memset(vis,0,sizeof(vis)); 44 for(int i=1;i<=n;i++) 45 if(!dfn[i]) root=i,tarjan(root); 46 int ans=0; 47 for(int i=1;i<=n;i++) 48 if(vis[i]) ans++; 49 printf("%d\n",ans); 50 for(int i=1;i<=n;i++) 51 if(vis[i]) printf("%d ",i); 52 return 0; 53 }