NYOJ 120 校园网络

校园网络

时间限制: 3000 ms  |  内存限制:65535 KB
难度: 5
 
描述

南阳理工学院共有M个系,分别编号1~M,其中各个系之间达成有一定的协议,如果某系有新软件可用时,该系将允许一些其它的系复制并使用该软件。但该允许关系是单向的,即:A系允许B系使用A的软件时,B未必一定允许A使用B的软件。

现在,请你写一个程序,根据各个系之间达成的协议情况,计算出最少需要添加多少个两系之间的这种允许关系,才能使任何一个系有软件使用的时候,其它所有系也都有软件可用。

 
输入
第一行输入一个整数T,表示测试数据的组数(T<10)
每组测试数据的第一行是一个整数M,表示共有M个系(2<=M<=100)。
随后的M行,每行都有一些整数,其中的第i行表示系i允许这几个系复制并使用系i的软件。每行结尾都是一个0,表示本行输入结束。如果某个系不允许其它任何系使用该系软件,则本行只有一个0.
输出
对于每组测试数据,输出最少需要添加的这种允许关系的个数。
样例输入
1

5

2 4 3 0

4 5 0

0

0

1 0
样例输出
2
来源
POJ改编
上传者
张云聪

解题:强连通算法+缩点。然后看缩点后的图,某点入度为0,加1,如果出度为0 再加1.

 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <cstdlib>

 5 #include <vector>

 6 #include <climits>

 7 #include <algorithm>

 8 #include <cmath>

 9 #include <stack>

10 #define LL long long

11 #define INF 0x3f3f3f

12 using namespace std;

13 const int maxn = 110;

14 vector<int>g[maxn],mp[maxn];

15 stack<int>s;

16 int low[maxn],dfn[maxn],belong[maxn],iindex;

17 bool instack[maxn],in[maxn],out[maxn];

18 int scc,n;

19 void tarjan(int u) {

20     dfn[u] = low[u] = ++iindex;

21     instack[u] = true;

22     s.push(u);

23     int v;

24     for(int i = 0; i < g[u].size(); i++) {

25         v = g[u][i];

26         if(!dfn[v]) {

27             tarjan(v);

28             low[u] = min(low[u],low[v]);

29         } else if(instack[v] && low[u] > dfn[v]) low[u] = dfn[v];

30     }

31     if(low[u] == dfn[u]) {

32         scc++;

33         do {

34             v = s.top();

35             instack[v] = false;

36             belong[v] = scc;

37             s.pop();

38         } while(v != u);

39     }

40 

41 }

42 int main() {

43     int t,i,j,u,v,ans;

44     scanf("%d",&t);

45     while(t--) {

46         scanf("%d",&n);

47         for(i = 0; i <= n; i++) {

48             g[i].clear();

49             low[i] = dfn[i] = 0;

50             instack[i] = false;

51             mp[i].clear();

52         }

53         for(i = 1; i <= n; i++) {

54             while(scanf("%d",&v)&&v) {

55                 g[i].push_back(v);

56             }

57         }

58         while(!s.empty()) s.pop();

59         ans = scc = iindex = 0;

60         for(i = 1; i <= n; i++)

61             if(dfn[i]) tarjan(i);

62         for(i = 1; i <= n; i++) {

63             for(j = 0; j < g[i].size(); j++) {

64                 if(belong[i] != belong[g[i][j]]) {

65                     mp[belong[i]].push_back(belong[g[i][j]]);

66                 }

67             }

68         }

69         ans = 0;

70         memset(in,false,sizeof(in));

71         memset(out,false,sizeof(out));

72         for(i = 1; i <= n; i++) {

73             for(j = 0; j < g[i].size(); j++) {

74                 out[i] = true;

75                 in[g[i][j]] = true;

76             }

77         }

78         for(i = 1; i <= n; i++) {

79             if(!in[i]) ans++;

80             if(!out[i]) ans++;

81         }

82         printf("%d\n",ans);

83     }

84     return 0;

85 }
View Code

 

 

你可能感兴趣的:(网络)