POJ 3660 Cow Contest(Floyd求傳遞閉包(可達矩陣))
Time Limit: 1000MS | Memory Limit: 65536K |
Total Submissions: 16341 | Accepted: 9146 |
Description
N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the competitors.
The contest is conducted in several head-to-head rounds, each between two cows. If cow A has a greater skill level than cow B (1 ≤ A ≤ N; 1 ≤ B ≤ N; A ≠ B), then cow A will always beat cow B.
Farmer John is trying to rank the cows by skill level. Given a list the results of M (1 ≤ M ≤ 4,500) two-cow rounds, determine the number of cows whose ranks can be precisely determined from the results. It is guaranteed that the results of the rounds will not be contradictory.
Input
* Line 1: Two space-separated integers: N and M
* Lines 2..M+1: Each line contains two space-separated integers that describe the competitors and results (the first integer, A, is the winner) of a single round of competition: A and B
Output
* Line 1: A single integer representing the number of cows whose ranks can be determined
Sample Input
5 5 4 3 4 2 3 2 1 2 2 5
Sample Output
2
Source
分析;給你n頭牛,m組關係,每組關係形式為A B,代表A比B厲害問你根據這些關係可以推出有幾頭牛的名次是確定的 如果一頭牛和其他的所有牛的關係都確定了的話,那麼該牛的名次也是確定的
關係的確定分兩種情況:
比如A和C
1.直接確定 題目直接告訴你了A比C厲害
2.間接確定 題目告訴你A比B厲害,B又比C厲害,那麼我們可以推出A比C厲害 所有我們必須考慮間接確定的情況,其實這種間接確定就是一個傳遞閉包
要求傳遞閉包的話我們必須確定可達矩陣
可達矩陣:G[i][j]=1的話,代表i和j之間是可以到達的(直接或者間接到達) 可達矩陣可以使用floyd演算法確定,雖然Floyd是求最短路的,但是也是可以求傳遞閉包(可達矩陣的)
#include<stdio.h> #include<iostream> #include<math.h> #include<string.h> #include<set> #include<map> #include<list> #include<queue> #include<algorithm> using namespace std; typedef long long LL; int mon1[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31}; int mon2[13]= {0,31,29,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}}; int getval() { int ret(0); char c; while((c=getchar())==' '||c=='\n'||c=='\r'); ret=c-'0'; while((c=getchar())!=' '&&c!='\n'&&c!='\r') ret=ret*10+c-'0'; return ret; } #define max_v 105 int G[max_v][max_v]; int n,m; void floyd()//求可達矩陣 { for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) continue; if(G[i][k]==1&&G[k][j]==1) G[i][j]=1; } } } } int main() { int x,y; while(~scanf("%d %d",&n,&m)) { memset(G,0,sizeof(G)); for(int i=1;i<=m;i++) { scanf("%d %d",&x,&y); G[x][y]=1; } floyd(); int sum=0; int cnt=0; for(int i=1;i<=n;i++) { cnt=0; for(int j=1;j<=n;j++) { //printf("%d ",G[i][j]); if(G[i][j]||G[j][i]) cnt++; } // printf("\n"); if(cnt==n-1)//存在某牛和其他n-1頭牛的關係直接或間接確定,那麼該牛名次確定 sum++; } printf("%d\n",sum); } return 0; } /* 分析;給你n頭牛,m組關係,每組關係形式為A B,代表A比B厲害 問你根據這些關係可以推出有幾頭牛的名次是確定的 如果一頭牛和其他的所有牛的關係都確定了的話,那麼該牛的名次也是確定的 關係的確定分兩種情況: 比如A和C 1.直接確定 題目直接告訴你了A比C厲害 2.間接確定 題目告訴你A比B厲害,B又比C厲害,那麼我們可以推出A比C厲害 所有我們必須考慮間接確定的情況,其實這種間接確定就是一個傳遞閉包 要求傳遞閉包的話我們必須確定可達矩陣 可達矩陣:G[i][j]=1的話,代表i和j之間是可以到達的(直接或者間接到達) 可達矩陣可以使用floyd演算法確定,雖然Floyd是求最短路的,但是也是可以求傳遞閉包(可達矩陣的) */