C++——【USACO 5.3.3】——Network of Schools

来源:互联网 发布:如何做好数据 编辑:程序博客网 时间:2024/05/22 11:41

Network of Schools
IOI '96 Day 1 Problem 3

A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the "receiving schools"). Note that if B is in the distribution list of school A, then A does not necessarily appear in the list of school B.

You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.

PROGRAM NAME: schlnet

INPUT FORMAT

The first line of the input file contains an integer N: the number of schools in the network (2<=N<=100). The schools are identified by the first N positive integers. Each of the next N lines describes a list of receivers. The line i+1 contains the identifiers of the receivers of school i. Each list ends with a 0. An empty list contains a 0 alone in the line.

SAMPLE INPUT (file schlnet.in)

52 4 3 04 5 0001 0

OUTPUT FORMAT

Your program should write two lines to the output file. The first line should contain one positive integer: the solution of subtask A. The second line should contain the solution of subtask B.

SAMPLE OUTPUT (file schlnet.out)

12

学校网络


许多学校的计算机网络相连。这些学校之间已经达成了协议:每所学校都有一份分发软件的学校名单(“接收学校”)。请注意,如果B在A学校的分配列表中,A并不一定出现在B学校的列表中。

你要编写一个程序,计算选择最小数量的学校来接受一份新的协议使信息可以通过网络传达到所有学校(子任务1)。作为一个进一步的任务,我们希望确保通过网络发送的信息可以到达任意学校。为了实现这一目标,我们可能需要扩大新成员的接收名单。计算最小的扩展数,这样无论我们将新软件发送到哪个学校,它都能到达所有其他学校(子任务2)。一个扩展意味着将一个新成员引入一个学校的接收器列表中。

项目名称:schlnet

输入格式

输入文件的第一行包含一个整数N:网络中的学校数(2 <=N<= 100)。下一个N行描述了一个接收者列表。第i + 1行包含学校i的接收对象的编号,每个列表以0结尾。空列表中包含一个单独的0。

示例输入(文件schlnet.in)

5

2 3 4 0

4 5 0

0

0

1 0

输出格式

你的程序应该写两行到输出文件。第一行应该包含一个正整数:子任务1的解。第二行应该包含子任务2的解。

样例输出(文件schlnet.out)

2




——为了省空间,我循环使用了一些变量。。


/*ID : mcdonne1LANG : C++TASK : schlnet*/#pragma GCC optimize("O3")#include <fstream>#include <cstring>#include <algorithm>using namespace std;int n, x, cnt, tot;int to[5000], next[5000], belong[101], first[101], in[101], out[101], st[101];pair <int, int> p[5000];bool vis[101];inline void add (int x, int y) {to[++cnt] = y;next[cnt] = first[x];first[x]  = cnt;}void dfs (int x) {vis[x] = true;for (int i = first[x]; i; i = next[i])if (!vis[to[i]])dfs (to[i]);st[++cnt] = x;}void redfs (int x) {vis[x] = true;belong[x] = tot;for (int i = first[x]; i; i = next[i])if (!vis[to[i]])redfs (to[i]);}int main () {FILE *fin = fopen("schlnet.in", "r");FILE *fout = fopen("schlnet.out", "w");fscanf (fin, "%d", &n);for (int i = 1; i <= n; i++)while (fscanf (fin, "%d", &x))if (x) add (i, x), p[cnt] = make_pair(i, x);else break;cnt = 0;for (int i = 1; i <= n; i++) if (!vis[i]) dfs (i);cnt = 0;memset (to, 0, sizeof(to));memset (vis, 0, sizeof(vis));memset (next, 0, sizeof(next));memset (first, 0, sizeof(first));fseek (fin, 0, SEEK_SET);fscanf (fin, "%d", &n);for (int i = 1; i <= n; i++) while (fscanf (fin, "%d", &x)) if (x) add (x, i); else break;for (int i = n; i >= 1; i--) if (!vis[st[i]]) ++tot, redfs (st[i]);for (int i = 1; i <= cnt; i++)if (belong[p[i].first] ^ belong[p[i].second])++out[belong[p[i].first]], ++in[belong[p[i].second]];x = cnt = 0;for (int i = 1; i <= tot; i++) {if (!in[i]) ++cnt;if (!out[i]) ++x;}if (tot == 1) fprintf (fout, "1\n0\n");else fprintf (fout, "%d\n%d\n", cnt, max (cnt, x));return 0;}


原创粉丝点击