Tarjan+缩点【强连通分量】【模板】

 
 

//Wannafly挑战赛14 C https://www.nowcoder.com/acm/contest/81/C

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=100005;
 4 struct edge{
 5     int from;
 6     int to;
 7     int next;
 8 }EDGE[maxn];
 9 vector<int>vc[maxn];
10 int head[maxn],dfn[maxn],vis[maxn],low[maxn],col[maxn],in[maxn],en[maxn],stk[maxn];//各个变量的意义可参照上篇博客
11 int edge_cnt=1,tot1=1,tot2=0,scc_cnt=0,tot0=0;
12 void add(int x,int y)
13 {
14     EDGE[edge_cnt].from=x;    
15     EDGE[edge_cnt].to=y;
16     EDGE[edge_cnt].next=head[x];
17     head[x]=edge_cnt++;
18 }
19 void Tarjan(int u)
20 {
21     low[u]=dfn[u]=tot1++;
22     vis[u]=1;
23     stk[++tot2]=u;
24     for(int i = head[u]; i != -1  ; i = EDGE[i].next)
25     {
26         if(!dfn[EDGE[i].to]){
27             Tarjan(EDGE[i].to);
28             low[u]=min(low[u],low[EDGE[i].to]);
29         }
30         else if(vis[EDGE[i].to]){
31             low[u]=min(low[u],low[EDGE[i].to]);
32         }
33     }
34             if(low[u]==dfn[u]){
35             int xx;
36             scc_cnt++;
37             do{
38                 xx=stk[tot2--];
39                 vc[scc_cnt].push_back(xx);
40                 col[xx]=scc_cnt;
41                 vis[xx]=0;
42             }while(xx!=u);
43         }
44 }
45 int main()
46 {
47     int n,m;
48     scanf("%d%d",&n,&m);
49     memset(head,-1,sizeof(head));
50     memset(in,0,sizeof(in));
51     while(m--)
52     {
53         int a,b;
54         scanf("%d%d",&a,&b);
55          add(a,b);
56     }
57     for(int i = 1 ; i <= n; i++)
58     {
59         if(!dfn[i])Tarjan(i);
60     }
61     for(int i = 1 ; i <= edge_cnt ; i++)
62     {
63         if(col[EDGE[i].from]!=col[EDGE[i].to])
64         {
65             in[col[EDGE[i].to]]++;//缩点
66         }
67     }
68     for(int i = 1 ; i <= scc_cnt ; i++)
69     {
70         if(in[i])
71         continue;
72         int mmin=vc[i][0];
73         for(int j = 1 ; j < vc[i].size() ; j++)
74         {
75             if(vc[i][j]<mmin)
76             mmin=vc[i][j];
77         }
78         en[tot0++]=mmin;
79     }
80 
81     printf("%d\n",tot0);
82     sort(en,en+tot0);
83     for(int i = 0 ; i < tot0 ; i++)
84     {
85         printf("%d",en[i]);
86         char c=(i==tot0-1)?'\n':' ';
87         printf("%c",c);
88     }
89     return 0;
90 }
91 /*4 5
92 1 3
93 2 4
94 4 2
95 1 4
96 2 1*/

猜你喜欢

转载自www.cnblogs.com/MekakuCityActor/p/8987108.html
今日推荐