POJ_1236 Network of School (Tarjan)
Tarjan 它好贱,wa了10+次。。。
思路:用“它贱”进行强连通缩点。然后统计缩点后的图中入度为0的点的个数in和出度为0的点到个数out。A就是in, B就是max(in, out);
渣代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <stack>
5
6 using namespace std;
7
8 const int N = 110;
9
10 struct node {
11 int to;
12 int next;
13 } g[N*N/2];
14
15 int head[N], blong[N];
16 int dfn[N], low[N];
17 int in[N], out[N];
18 int t, cnt, ind;
19 bool vis[N];
20
21 stack<int> s;
22
23 void init() {
24 memset(g, 0, sizeof(g));
25 memset(head, 0, sizeof(head));
26 memset(blong, 0, sizeof(blong));
27 memset(dfn, 0, sizeof(dfn));
28 memset(low, 0, sizeof(low));
29 memset(in, 0, sizeof(in));
30 memset(out, 0, sizeof(out));
31 memset(vis, 0, sizeof(vis));
32 t = 1; cnt = ind = 0;
33 }
34
35 void add(int u, int v) {
36 g[t].to = v; g[t].next = head[u]; head[u] = t++;
37 }
38
39 void tarjan(int u) {
40 int v, i;
41 vis[u] = true;
42 s.push(u);
43 low[u] = dfn[u] = ++ind;
44 for(i = head[u]; i; i = g[i].next) {
45 v = g[i].to;
46 if(!dfn[v]) {
47 tarjan(v);
48 low[u] = min(low[u], low[v]);
49 } else if(vis[v]) {
50 low[u] = min(low[u], dfn[v]);
51 }
52 }
53 if(low[u] == dfn[u]) {
54 cnt++;
55 do {
56 v = s.top();
57 s.pop();
58 //printf("%d %d\n", v, cnt);
59 blong[v] = cnt;
60 vis[v] = false;
61 } while(v != u);
62 }
63 }
64
65 int main() {
66 //freopen("data.in","r", stdin);
67
68 int i, j, v, a, b, n;
69 while(~scanf("%d", &n)) {
70 init();
71 for(i = 1; i <= n; i++) {
72 while(scanf("%d", &v), v) {
73 add(i, v);
74 }
75 }
76
77 for(i = 1; i <= n; i++) {
78 if(!dfn[i]) tarjan(i);
79 }
80
81 for(i = 1; i <= n; i++) {
82 for(j = head[i]; j; j = g[j].next) {
83 v = g[j].to;
84 if(blong[i] != blong[v]) {
85 in[blong[v]]++; out[blong[i]]++;
86 }
87 }
88 }
89 a = b = 0;
90 for(i = 1; i <= cnt; i++) {
91 if(!in[i]) a++;
92 if(!out[i]) b++;
93 }
94 printf("%d\n", a);
95 if(cnt == 1) printf("0\n");
96 else printf("%d\n", max(a, b));
97 }
98 return 0;
99 }