poj 1236 Network of Schools

强联通分量模版题,tarjan算法:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define MAXN 110
 4 
 5 int n, p, ans1, ans2, u[MAXN*MAXN], v[MAXN*MAXN], next[MAXN*MAXN], first[MAXN];
 6 int dfn[MAXN], low[MAXN], col[MAXN], stk[MAXN], ins[MAXN], ind, top, cols, tmp;
 7 int indg[MAXN], outdg[MAXN], zeroin, zeroout;
 8 
 9 void dfs(int u)
10 {
11     dfn[u] = low[u] = ++ind;
12     stk[++top] = u, ins[u] = 1;
13     for(int i = first[u]; i != -1; i = next[i])
14     {
15         int ve = v[i];
16         if(!dfn[ve])
17         {
18             dfs(ve);
19             if(low[ve] < low[u]) low[u] = low[ve];
20         }
21         else if(ins[ve])
22         {
23             if(dfn[ve] < low[u]) low[u] = dfn[ve];
24         }
25     }
26     if(dfn[u] == low[u])
27     {
28         cols ++;
29         do
30         {
31             tmp = stk[top--];
32             col[tmp] = cols;
33             ins[tmp] = 0;
34         }
35         while(tmp != u);
36     }
37 }
38 
39 void tarjan(int n)
40 {
41     memset(dfn, 0, sizeof(dfn));
42     memset(low, 0, sizeof(low));
43     memset(col, 0, sizeof(col));
44     memset(stk, 0, sizeof(stk));
45     memset(ins, 0, sizeof(ins));
46     ind = top = cols = 0;
47     for(int i = 1; i <= n; i ++)
48     {
49         if(!dfn[i]) dfs(i);
50     }    
51     if(cols == 1)
52     {
53         ans1 = 1, ans2 = 0;
54         return;
55     }
56     ans1 = ans2 = zeroin = zeroout = 0;
57     memset(indg, 0, sizeof(indg));
58     memset(outdg, 0, sizeof(outdg));
59     for(int u = 1; u <= n; u ++)
60     {
61         for(int i = first[u]; i != -1; i = next[i])
62         {
63             int ve = v[i];
64             if(col[u] == col[ve]) continue;
65             indg[col[ve]] ++;
66             outdg[col[u]] ++;
67         }
68     }
69     for(int i = 1; i <= cols; i ++)
70     {
71         if(indg[i] == 0) zeroin ++;
72         if(outdg[i] == 0) zeroout ++;
73     }
74     ans1 = zeroin;
75     ans2 = zeroin > zeroout ? zeroin : zeroout;
76 }
77 
78 int main()
79 {
80     while(~scanf("%d",&n))
81     {
82         memset(first, -1, sizeof(first));
83         p = 0;
84         for(int i = 1; i <= n; i ++)
85             while(1)
86             {
87                 int a;
88                 scanf("%d",&a);
89                 if(a == 0) break;
90                 u[p] = i; v[p] = a;
91                 next[p] = first[u[p]];
92                 first[u[p]] = p;
93                 p ++;
94             }
95             tarjan(n);
96             printf("%d\n%d\n",ans1, ans2);
97     }
98     return 0;
99 }
posted on 2012-08-07 10:12  BFP  阅读(179)  评论(0编辑  收藏  举报