poj - 1236 Network of Schools

原文链接: http://www.cnblogs.com/lzxskjo/archive/2012/08/29/2661088.html

强连通分量题,涉及求强连通分量和缩点,基本是抄的模板,我也是把这题的代码当模板放这里。

做这题的一个收获,缩点后为构造强连通分量,最少要添加几条有向边:统计入度和出度为0的点的数量,取其大者。

 1 #include 
 2 #include <string.h>
 3 #include 
 4 using namespace std;
 5 const int N = 105;
 6 int stk[N],col[N],dep[N],low[N];
 7 int cnt,cols,top,ans1,ans2;
 8 bool inq[N];
 9 vector <int> a[N];
10 void DFS(int u)
11 {
12     int i,t,l,v;
13     l = a[u].size();
14     dep[u] = low[u] = ++cnt;
15     stk[top++] = u;
16     inq[u] = 1;
17     for(i = 0; i < l; i++)
18     {
19         v = a[u][i];
20         if(!dep[v])
21         {
22             DFS(v);
23             if(low[v] < low[u])
24                 low[u] = low[v];
25         }
26         else if(inq[v])
27         {
28             if(dep[v] < low[u])
29                 low[u] = dep[v];
30         }
31     }
32     if(dep[u] == low[u])
33     {
34         cols++;
35         do{
36             t = stk[--top];
37             inq[t] = 0;
38             col[t] = cols;
39         }while(t != u);
40     }
41 }
42 void Tarjan(int n)
43 {
44     int in0=0,out0=0,i,j,l,v;
45     int in[N],out[N];
46     cnt = top = cols = 0;
47     memset(inq,0,sizeof inq);
48     memset(dep,0,sizeof dep);
49     memset(low,0,sizeof low);
50     for(i = 1; i <= n; i++)
51         if(!dep[i]) DFS(i);
52     if(cols == 1)
53     {
54         ans1 = 1;
55         ans2 = 0;
56         return ;
57     }
58     memset(in,0,sizeof in);
59     memset(out,0,sizeof out);
60     for(i = 1; i <= n; i++)
61     {
62         l = a[i].size();
63         for(j = 0; j < l; j++)
64         {
65             v = a[i][j];
66             if(col[i] != col[v])
67                 out[col[i]]++, in[col[v]]++;
68         }
69     }
70     for(i = 1; i <= cols; i++)
71     {
72         if(!in[i]) in0++;
73         if(!out[i]) out0++;
74     }
75     ans1 = in0;
76     ans2 = in0 > out0 ?in0 :out0 ;
77 }
78 int main()
79 {
80     int n,i,t;
81     while(~scanf("%d",&n))
82     {
83         for(i = 1; i <= n; i++)
84         while(scanf("%d",&t),t)
85             a[i].push_back(t);
86         Tarjan(n);
87         printf("%d\n%d\n",ans1,ans2);
88     }
89     return 0;
90 }

转载于:https://www.cnblogs.com/lzxskjo/archive/2012/08/29/2661088.html

你可能感兴趣的:(poj - 1236 Network of Schools)