有点类似方老师和农场,但是由于是单向边,所以不能按叶子处理,找到出度或者入度为0的最大数目即可。
。。。一定要注意初始化全面!!!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip> 10 #include<climits> 11 #include<cmath> 12 #include<stdlib.h> 13 #include<vector> 14 #include<stack> 15 #include<set> 16 #define INF 2000000000 17 #define MAXN 110 18 #define maxn 100010 19 #define Mod 1000007 20 #define N 1010 21 using namespace std; 22 typedef long long LL; 23 24 vector<int> G1[maxn], G2[maxn]; 25 int dfn[maxn], low[maxn], instk[maxn], bel[maxn]; 26 int Time, scc_cnt, ans; 27 int vis[maxn]; 28 int ind[maxn], outd[maxn]; 29 int n, m, u, v; 30 int x, y, z; 31 stack<int> S; 32 33 void init() 34 { 35 for (int i = 0; i <= n; ++i) { 36 G1[i].clear(); 37 G2[i].clear(); 38 vis[i] = 0; 39 ind[i] = 0; 40 outd[i] = 0; 41 dfn[i] = 0; 42 low[i] = 0; 43 } 44 Time = scc_cnt; 45 while (!S.empty()) S.pop(); 46 } 47 48 void read() 49 { 50 scanf("%d", &n); 51 for (int i = 1; i <= n; ++i) { 52 while (scanf("%d", &m),m) 53 G1[i].push_back(m); 54 } 55 } 56 57 void Tarjan(int u) 58 { 59 dfn[u] = low[u] = ++Time; 60 S.push(u); 61 instk[u] = 1; 62 for (int i = 0; i < G1[u].size(); ++i) { 63 int v = G1[u][i]; 64 if (!dfn[v]) { 65 Tarjan(v); 66 low[u] = min(low[u], low[v]); 67 } 68 else if (instk[v]) 69 low[u] = min(low[u], dfn[v]); 70 } 71 if (low[u] == dfn[u]) { 72 scc_cnt++; 73 int v; 74 do { 75 v = S.top(); 76 S.pop(); 77 instk[v] = 0; 78 bel[v] = scc_cnt; 79 } while (v != u); 80 } 81 } 82 83 void rebuild() 84 { 85 for (int i = 1; i <= n; ++i) 86 for (int j = 0; j < G1[i].size(); ++j) { 87 u = bel[i]; 88 v = bel[G1[i][j]]; 89 if (u != v) { 90 G2[u].push_back(v); 91 ind[v]++; 92 outd[u]++; 93 } 94 95 } 96 int In = 0, Out = 0; 97 for (int i = 1; i <= scc_cnt; ++i) { 98 if (!ind[i]) In++; 99 if (!outd[i]) Out++; 100 } 101 if (scc_cnt == 1) cout << 0 << endl; 102 else cout << max(In, Out) << endl; 103 } 104 105 void find_scc() 106 { 107 for (int i = 1; i <= n; ++i) 108 if (!dfn[i]) Tarjan(i); 109 } 110 111 112 int main() 113 { 114 int T; 115 scanf("%d", &T); 116 while (T--) { 117 init(); 118 read(); 119 find_scc(); 120 rebuild(); 121 } 122 return 0; 123 }