/*
*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 }
posted on 2012-08-17 18:03  cchun  阅读(1522)  评论(0编辑  收藏  举报