/* *State: POJ3660 Accepted 208K 32MS C++ 960B *题目大意: * 有n只奶牛,有n个连续的实力,如果u的实力大于v的实力,就能打赢它, * 然后给定m种关系,求最后能确定其排名的奶牛个数。 *解题思路: * 一开始用dij的最长路去求,发现有一种典型的DAG求不了,而传递闭包可以 * 快速求解。其实dij可行,但是麻烦。没有floyd那么简洁优美啊。用floyd,求 * 出每个点能到达的点。如果有一个点,排名在它之前的和排名在它之后的点之 * 和为n-1,那么它的排名就是确定的。 */
View Code
1 #include <iostream> 2 using namespace std; 3 4 const int MAXN = 105; 5 int Map[MAXN][MAXN]; 6 7 void init(int n) 8 { 9 for(int i = 0; i <= n; i++) 10 { 11 for(int j = 0; j <= n; j++) 12 { 13 Map[i][j] = (i == j ? 1 : 0); 14 } 15 } 16 } 17 18 void floyd(int n) 19 { 20 for(int k = 1; k <= n; k++) 21 { 22 for(int i = 1; i <= n; i++) 23 { 24 for(int j = 1; j <= n; j++) 25 { 26 Map[i][j] = Map[i][j] || (Map[i][k] & Map[k][j]); 27 } 28 } 29 } 30 } 31 32 int main(void) 33 { 34 #ifndef ONLINE_JUDGE 35 freopen("in.txt", "r", stdin); 36 #endif 37 38 int n, m; 39 while(scanf("%d %d", &n, &m) == 2) 40 { 41 init(n); 42 int u, v; 43 for(int i = 0; i < m; i++) 44 { 45 scanf("%d %d", &u, &v); 46 Map[u][v] = 1; 47 } 48 floyd(n); 49 int sol = 0; 50 51 52 for(int i = 1; i <= n; i++) 53 { 54 int cnt = 0; 55 for(int j = 1; j <= n; j++) 56 { 57 if(Map[j][i]) 58 cnt++; 59 if(Map[i][j]) 60 cnt++; 61 } 62 if(cnt == n + 1) 63 sol++; 64 } 65 printf("%d\n", sol); 66 } 67 return 0; 68 }