校园网络
时间限制: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 }
NYOJ 120 校园网络
时间: 2024-10-23 22:36:03