POJ 1236 Network of Schools(强连通分量)

 

题目大意

 

有 n(2<=n<=100) 所学校,每个学校都有个 list,列出了这个学校提供软件的学校名单。

现在问:

        A、为了使所有的学校享用到一个软件,最少有多少学校要 copy 一个软件

        B、为了使传到任意学校的软件能够传到其他所有的学校,至少要添加多少个学校到相应学校的 list 中去

 

做法分析

 

这种题,显然要先给图“化简”,是其成为一个 DAG 图

对于 task A,我们只需统计“化简”后的 DAG 中入度为 0 的点的个数

对于 task B,其实就是求添加多少条边使得 DAG 之间的所有点能够相互到达(形成一个 SCC),有一个结论:答案是入度为 0 的点的个数和出度为 0 的点个数的最大者

 

参考代码

 

POJ 1236
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <vector>
 5 #include <stack>
 6 
 7 using namespace std;
 8 
 9 const int N=106;
10 
11 vector <int> arc[N];
12 int dfn[N], low[N], id[N];
13 int n, T, ind;
14 stack <int> s;
15 bool vs[N];
16 
17 void tarjan(int u)
18 {
19     vs[u]=1, s.push(u);
20     dfn[u]=low[u]=T++;
21     int len=(int)arc[u].size();
22     for(int i=0; i<len; i++)
23     {
24         int v=arc[u][i];
25         if(dfn[v]==-1)
26         {
27             tarjan(v);
28             if(low[u]>low[v]) low[u]=low[v];
29         }
30         else if(vs[v] && low[u]>dfn[v]) low[u]=dfn[v];
31     }
32     if(low[u]==dfn[u])
33     {
34         for(int v; 1; )
35         {
36             v=s.top();
37             s.pop(), vs[v]=0;
38             id[v]=ind;
39             if(v==u) break;
40         }
41         ind++;
42     }
43 }
44 
45 int main()
46 {
47     scanf("%d", &n);
48     for(int i=1, u; i<=n; i++)
49     {
50         arc[i].clear();
51         while(scanf("%d", &u), u!=0) arc[i].push_back(u);
52     }
53     for(int i=1; i<=n; i++) dfn[i]=-1, vs[i]=0;
54     while(!s.empty()) s.pop();
55     ind=T=0;
56     for(int i=1; i<=n; i++) if(dfn[i]==-1) tarjan(i);
57     for(int i=0; i<ind; i++) dfn[i]=low[i]=0;
58     for(int i=1; i<=n; i++)
59     {
60         int len=(int)arc[i].size(), u=id[i];
61         for(int j=0; j<len; j++)
62         {
63             int v=id[arc[i][j]];
64             if(u!=v) dfn[u]++, low[v]++;
65         }
66     }
67     int ans1=0, ans2=0;
68     for(int i=0; i<ind; i++)
69     {
70         if(low[i]==0) ans1++;
71         if(dfn[i]==0) ans2++;
72     }
73     ans2=max(ans1, ans2);
74     if(ind==1) ans1=1, ans2=0;
75     printf("%d\n%d\n", ans1, ans2);
76     return 0;
77 }

AC通道

POJ 1236 Network of Schools

原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2963984.html