校园网络

来源:互联网 发布:接触角测定仪软件 编辑:程序博客网 时间:2024/06/08 19:18

校园网络

时间限制: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.
输出
对于每组测试数据,输出最少需要添加的这种允许关系的个数。
样例输入
152 4 3 04 5 0001 0
样例输出
2


求强连通分量的tarjan算法,先求出各个强连通分量,再缩点,之后答案就是缩点后的DAG上入度为0与出度为0的点的个数中较大的那一个

#include <stdio.h>#include <string.h>#include <stdlib.h>#define min(x, y) (x) < (y) ? (x) : (y)const int AER_MAX = 1000;struct ArcNode{int v;struct ArcNode *next;};struct ArcNode *head[AER_MAX];int stack[AER_MAX], top = 0;int dfn[AER_MAX], low[AER_MAX];int in[AER_MAX], out[AER_MAX];int time;int res;int t[AER_MAX];void tarjan(int v){dfn[v] = low[v] = time++;stack[top++] = v;for(struct ArcNode *p = head[v]; p != NULL; p = p->next){if(!dfn[p->v]){tarjan(p->v);low[v] = min(low[v], low[p->v]);}else{low[v] = min(low[v], dfn[p->v]);}}if(dfn[v] == low[v]){res++;do{v = stack[--top];t[v] = res;}while(dfn[v] != low[v]);}}void destory(int m){struct ArcNode *p, *q;for(int i = 1; i <= m; ++i){for(q = NULL, p = head[i]; p != NULL; q = p, p = p->next){if(q)free(q);}if(q)free(q);}}int main(void){int n, m;scanf("%d", &n);while(n--){scanf("%d", &m);res = 0;time = 1;memset(in, 0, sizeof(in));memset(out, 0, sizeof(out));memset(dfn, 0, sizeof(dfn));memset(head, 0, sizeof(head));memset(low, 0, sizeof(low));memset(t, 0, sizeof(t));top = 0;for(int i = 1; i <= m; ++i){int r;struct ArcNode *rear = head[i];while(scanf("%d", &r), r){if(!rear){rear = (struct ArcNode *)malloc(sizeof(struct ArcNode));head[i] = rear;}else{rear->next = (struct ArcNode *)malloc(sizeof(struct ArcNode));rear = rear->next;}rear->next = NULL;rear->v = r;}}for(int i = 1; i <= m; ++i){if(!dfn[i])tarjan(i);}for(int i = 1; i <= m; ++i){for(struct ArcNode *p = head[i]; p != NULL; p = p->next){in[t[i]]++;out[t[p->v]]++;}}int tx = 0, ty = 0;for(int i = 1; i <= res; ++i){if(in[i] == 0)tx++;else if(out[i] == 0)ty++;}if(res == 1){printf("%d\n", 0);}else{printf("%d\n", tx > ty ? tx : ty);}destory(m);}return 0;}        





原创粉丝点击