/*
*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 }