tarjan 强联通分量和割点

 1 #include<cstdio> 
 2 #include<cstring>
 3 #include<cmath>
 4 #include<ctime>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<stack>
 9 #include<set>
10 #define esp (1e-6)
11 #define inf (0x3f3f3f3f)
12 #define l(a) ((a)<<1)
13 #define r(a) ((a)<<1|1)
14 #define b(a) (1<<(a))
15 #define rep(i,a,b) for(int i=a;i<=(b);i++)
16 #define clr(a) memset(a,0,sizeof(a))
17 typedef long long ll;
18 typedef unsigned long long ull;
19 using namespace std;
20 int readint(){
21     int t=0,f=1;char c=getchar();
22     while(!isdigit(c)){
23         if(c=='-') f=-1;
24         c=getchar();
25     }
26     while(isdigit(c)){
27         t=(t<<3)+(t<<1)+c-'0';
28         c=getchar();
29     }
30     return t*f;
31 }
32 const int maxn=100009,maxm=200009;
33 struct edge{
34     int v;
35     edge*next;
36 }e[maxm],*pt=e,*fir[maxn];
37 int n,m,ans,dfstime,scccnt,size[maxn],pre[maxn],low[maxn],scc[maxn];
38 bool p[maxn];
39 void add(int u,int v){
40     pt->v=v;pt->next=fir[u];
41     fir[u]=pt++;
42 }
43 void addedge(int u,int v){
44     add(u,v);add(v,u);
45 }
46 stack<int>S;
47 void dfs(int x,int f){
48     int son=0;
49     pre[x]=low[x]=++dfstime;S.push(x);
50     for(edge*e=fir[x];e;e=e->next) if(e->v!=f){
51         if(!pre[e->v]){
52             son++;dfs(e->v,x);
53             low[x]=min(low[x],low[e->v]);
54             if(f!=-1&&low[e->v]>=pre[x]) p[x]=1;
55         }else if(!scc[e->v]) low[x]=min(low[x],pre[e->v]);
56     }
57     if(f==-1&&son>1) if(!p[x]) p[x]=1;
58     if(pre[x]==low[x]){
59         int t=-1;++scccnt;
60         while(t!=x){
61             t=S.top();S.pop();
62             scc[t]=scccnt;size[scccnt]++;
63         }
64     }
65 }
66 void tarjan(){
67     rep(i,1,n) if(!scc[i]) dfs(i,-1);
68     rep(i,1,n) if(p[i]) ans++;
69     cout<<ans<<endl;
70     rep(i,1,n) if(p[i]){
71         ans--;printf("%d",i);
72         putchar(ans?' ':'\n');
73     }
74 }
75 int main(){
76     //freopen("#input.txt","r",stdin);
77     //freopen("#output.txt","w",stdout);
78     n=readint();m=readint();
79     rep(i,1,m){
80         int U=readint(),V=readint();
81         addedge(U,V);
82     }
83     tarjan();
84     //fclose(stdin);
85     //fclose(stdout);
86     return 0;
87 }
View Code

 

posted @ 2017-12-21 00:32  ChenThree  阅读(99)  评论(0编辑  收藏  举报