ACM复习(12)8618大牛之路II

来源:互联网 发布:女淘宝网店铺名字大全 编辑:程序博客网 时间:2024/06/07 12:28

Description
要成为ACM大牛,要掌握很多必需的知识点。某些知识点可以推导出别的知识点,所以在比赛中遇到的新问题,很多时候可以由你学过的知识中推导得到。现在给出要掌握的所有知识点数及知识点之间的推导关系。注意,若A知识可以直接(间接)推导出B知识,B知识也是有可能直接(间接)推导出A知识的。一个新手想尽快具有解决所有知识点的能力,他至少需要掌握多少知识呢?

输入格式
多组数据,每组数据格式为:
第一行1<=n<=18,0<=m<=n*n.。n表示必需掌握的知识点数目,编号0~n-1。m为知识点间推导关系总数。接下来m行,每行A B两个数,表示从A知识可以推导出B知识。
当n==0 && m==0时,结束程序。两个Case间有一空行。

输出格式
一个数x,表示最少要掌握的知识数。

输入样例
8 4
0 1
0 2
1 3
1 4

2 2
0 1
1 0

0 0

输出样例
4
1


解题思路

和大牛之路I只有一句话不同:
1. 若A知识能直接(或间接)推导出B知识,那么B知识是无法直接(或间接)推导出A知识的
2. 若A知识可以直接(间接)推导出B知识,B知识也是有可能直接(间接)推导出A知识的

其实只要确定了A可以推导出B,B能不能推导出A都无所谓,因为反正都是同一组的,所以在大牛之路I的解法上再加一层循环读取数据就可以了

#include<stdio.h>int boss[20];int find(int n);int main(){    int n, m, a, b, count;    while(scanf("%d %d", &n, &m) && (n || m))    {        count = 0;        for(int i = 0; i < n; i ++)            boss[i] = i;        for(int i = 0; i < m; i ++)        {            scanf("%d %d", &a, &b);            boss[b] = find(a);        }        for(int i = 0; i < n; i ++)            if(boss[i] == i)                 count ++;        printf("%d\n", count );    }    return 0;}int find(int n){    while(boss[n] != n)        n = boss[n];    return n;}

原创粉丝点击