POJ 2553 The Bottom of a Graph

题目传送门

题目中文大意:

对于一些点,任意一个点都互相可达,则这些点称为"汇".求每一个"汇"的所有点.

解题思路:

tarjan求强连通分量,缩点,对于所有没有出度的强连通分量的点,就是答案.

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<stack>
 4 #include<cstring>
 5 #include<vector>
 6 #include<algorithm>
 7 
 8 using namespace std;
 9 
10 int n,m,head[5001],tot,dfn[5001],low[5001],_tot,tt,belong[5001],outd[5001],ans[5001],k;
11 bool _in[5001];
12 struct kkk {
13     int to,next;
14 }e[25000001];
15 stack<int> a;
16 
17 inline void chushihua() {
18     memset(head,-1,sizeof(head));
19     memset(belong,0,sizeof(belong));
20     memset(dfn,0,sizeof(dfn));
21     memset(low,0,sizeof(low));
22     memset(outd,0,sizeof(outd));
23     memset(ans,0,sizeof(ans));
24     tot = _tot = tt = k = 0;
25     memset(_in,0,sizeof(_in));
26 }
27 
28 inline void add(int x,int y) {
29     e[++tot].next = head[x];
30     e[tot].to = y;
31     head[x] = tot;
32 }
33 
34 inline void tarjan(int x) {
35     int v;
36     a.push(x);
37     dfn[x] = low[x] = ++_tot;
38     _in[x] = true;
39     for(int i = head[x];i != -1; i = e[i].next) {
40         v = e[i].to;
41         if(!dfn[v]) {
42             tarjan(v);
43             low[x] = min(low[x],low[v]);
44         }
45         else 
46             if(_in[v])
47                 low[x] = min(low[x],dfn[v]);
48     }
49     if(dfn[x] == low[x]) {
50         ++tt;
51         do {
52             v = a.top();
53             a.pop();
54             _in[v] = false;
55             belong[v] = tt;
56         }
57         while(v != x);
58     }
59 }
60 
61 inline void _ans(int x) {
62     for(int i = 1;i <= n; i++)
63         if(belong[i] == x)
64             ans[++k] = i;
65 }
66 
67 inline void _print() {
68     sort(ans+1,ans+k+1);
69     for(int i = 1;i <= k; i++)
70         printf("%d ",ans[i]);
71     printf("
"); 
72 }
73 
74 int main()
75 {
76     while(true) {
77         chushihua();
78         scanf("%d",&n);
79         if(n == 0) return 0;
80         scanf("%d",&m);
81         for(int i = 1;i <= m; i++) {
82             int x,y;
83             scanf("%d%d",&x,&y);
84             add(x,y);
85         }
86         for(int i = 1;i <= n; i++)
87             if(!dfn[i])
88                 tarjan(i);
89         for(int i = 1;i <= n; i++)
90             for(int j = head[i];j != -1; j = e[j].next) 
91                 if(belong[i] != belong[e[j].to])
92                     outd[belong[i]]++;
93         for(int i = 1;i <= tt; i++) 
94             if(outd[i] == 0)
95                 _ans(i);
96         _print();        
97     }
98     return 0;
99 }
原文地址:https://www.cnblogs.com/lipeiyi520/p/11440229.html