Tarjan+shrink point [strongly connected component] [template]

 
 

//Wannafly Challenge 14C 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];//each The meaning of the variable can refer to the previous blog
 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*/

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325254009&siteId=291194637