有n(1<=n<=100)个学生参加编程比赛。
给出m条实力信息。(1<=M<=4500)
其中每一条的格式为 A B (1<=A<=N,1<=B<=N,A!=B) 意思是A的实力比B强。
如果A比B强且B比C强,那么A一定比C强。
问最后有多少名学生可以确定他的排名。
保证输入信息不存在矛盾
第一行n和m。
以下m行 A B 表示A实力比B强。
输出答案
5 5 4 3 4 2 3 2 1 2 2 5
2
思路:这几天复习离散,没想到用到了一个知识点,用到了传递闭包的知识点,其实每个人都懂,很简单,不用知道传递闭包是什么。用Floyd,如果e[i][k]和e[k][j] 连通的话,就将e[i][j]连通。最后查找每个点与其余几个点相连通,如果与另外n-1个点相连通,就+1就行了。具体请看代码:
#include <stdio.h> #include <string.h> #define inf 0x3f3f3f3f int e[105][105]; void init(int n) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { e[i][j] = 0; } } } void Floyd(int n) { for(int k = 1; k <= n; k++) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(e[i][k] && e[k][j]) { e[i][j] = 1; } } } } } int main() { int n, m; int u, v; scanf("%d %d",&n, &m); init(n); for(int i = 1; i <= m; i++) { scanf("%d %d",&u, &v); e[u][v] = 1; } Floyd(n); int sum = 0, s; for(int i = 1; i <= n; i++) { s = 1; for(int j = 1; j <= n; j++) { if(i == j) continue; if(e[i][j] || e[j][i]) s++; } if(s == n) sum++; } printf("%d\n",sum); return 0; }