啥都不会啊!怎么办啊!

Fitz

慢慢来生活总会好起来的!!!

poj~1236 Network of Schools 强连通入门题

一些学校连接到计算机网络。这些学校之间已经达成了协议:

每所学校都有一份分发软件的学校名单(“接收学校”)。

请注意,如果B在学校A的分发名单中,则A不一定出现在学校B的名单中
您需要编写一个计划,计算必须接收新软件副本的最少学校数量,

以便软件根据协议(子任务A)到达网络中的所有学校。作为进一步的任务,

我们希望确保通过将新软件的副本发送到任意学校,该软件将覆盖网络中的所有学校。

为了实现这一目标,我们可能需要扩大新成员的接收者名单。

计算必须做的扩展的最小数目,以便我们发送新软件的任何学校,

它将到达所有其他学校(Subtask B)。

一种扩展意味着将一名新成员引入一所学校的接收者名单。

 

这题强连通水题 ,模板题目,

第一问求出最少要几个点才能到任意点

其实就是一个强连通缩点后,求出有几个入度为0的点,

第二问求出要加上几条边把所点后的有向无环图变成一个强连通图

就是求 max(sumin, sumout)

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 
 8 const int maxn = 1e5 + 10;
 9 int n, m, u, v, tot, top, cnt, flag;
10 struct node {
11     int v, next;
12 } edge[maxn];
13 int head[maxn], instack[maxn], s[maxn];
14 int dfn[maxn], low[maxn], belong[maxn];
15 void init() {
16     tot = cnt = top = flag = 0;
17     memset(s, 0, sizeof(s));
18     memset(head, -1, sizeof(head));
19     memset(dfn, 0, sizeof(dfn));
20     memset(instack, 0, sizeof(instack));
21 }
22 void add(int u, int v) {
23     edge[tot].v = v;
24     edge[tot].next = head[u];
25     head[u] = tot++;
26 }
27 void tarjin(int v) {
28     dfn[v] = low[v] = ++flag;
29     instack[v] = 1;
30     s[top++] = v;
31     for (int i = head[v] ; i != -1 ; i = edge[i].next) {
32         int j = edge[i].v;
33         if (!dfn[j]) {
34             tarjin(j);
35             low[v] = min(low[v], low[j]);
36         } else if (instack[j]) low[v] = min(low[v], dfn[j]);
37     }
38     if (dfn[v] == low[v]) {
39         cnt++;
40         int t;
41         do {
42             t = s[--top];
43             instack[t] = 0;
44             belong[t] = cnt;
45         } while(t != v) ;
46     }
47 }
48 void solve() {
49     for (int i = 1 ; i <= n ; i++)
50         if (!dfn[i]) tarjin(i);
51 }
52 int in[maxn], out[maxn];
53 int main() {
54     while(scanf("%d", &n) != EOF) {
55         init();
56         memset(in, 0, sizeof(in));
57         memset(out, 0, sizeof(out)) ;
58         for (int i = 1 ; i <= n ; i++) {
59             int v;
60             scanf("%d", &v);
61             while(v) {
62                 add(i, v);
63                 scanf("%d", &v);
64             }
65         }
66         for (int i = 1  ; i <= n ; i++)
67             if (!dfn[i]) tarjin(i);
68         for (int i = 1 ; i <= n ; i++) {
69             for (int j = head[i] ; ~j ; j = edge[j].next) {
70                 if (belong[edge[j].v] != belong[i]) {
71                     in[belong[edge[j].v]]++;
72                     out[belong[i]]++;
73                 }
74             }
75         }
76         int sumin = 0, sumout = 0;
77         for (int i = 1 ; i <= cnt ; i++) {
78             if (!in[i]) sumin++;
79             if (!out[i])sumout++;
80         }
81         printf("%d\n", sumin);
82         if (cnt == 1) printf("0\n");
83         else printf("%d\n", max(sumin, sumout));
84     }
85     return 0;
86 }

 

posted @ 2018-05-22 17:29  Fitz~  阅读(406)  评论(0编辑  收藏  举报