【洛谷P3388】割点

这是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 }
AC Code

猜你喜欢

转载自www.cnblogs.com/shl-blog/p/10807632.html