HDU 产生冠军 2094

解题思路:这题重在分析,可能你知道的越多,这题想得越多,什么并查集,什么有向图等。

        事实是,我们会发现,只要找到一个,并且仅有一个的入度为0的点,说明可以找出

      冠军。若入度为0的点一个都没有,说明每个选手都是输过的;若入度为0的点超过一个,

     说明多个对应的入度为0的点的关系是不确定的,也不能产生冠军。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define N 1005
 6 char s1[N], s2[N], str[N][N];
 7 int vis[N], cnt;
 8 
 9 int Change(char s[])
10 {
11     int i;
12     for(i = 0; i < cnt; i++)
13     {
14         //如果此字符串之前出现过,直接返回之间对应的标号。
15         if(strcmp(str[i], s) == 0) return i;
16     }
17     //如果此字符串之前没有出现过,则先将其存入字符数组中。
18     if(i == cnt) strcpy(str[cnt++], s); 
19     return i;
20 }
21 int main()
22 {
23     int n;
24     while(~scanf("%d", &n) && n)
25     {
26         memset(vis, 0, sizeof(vis));//注意初始化
27         cnt = 0;
28         while(n--)
29         {
30             scanf("%s %s", s1, s2);
31             int p1 = Change(s1);
32             int p2 = Change(s2);
33             vis[p2] = 1;
34         }
35         int cnt1 = 0;
36         for(int i = 0; i < cnt; i ++) //这里的<符号是不能为<=符号的
37         {
38             if(vis[i] == 0) cnt1 ++; //如果出现入度为0的,加1
39             //printf("vis[%d] = %d\n", i, vis[i]); //打印出来有利于debug
40             if(cnt1 > 1) break;
41         }
42         if(cnt1 == 1) printf("Yes\n"); //有且只有一个入度为0的,说明找出冠军。
43         else printf("No\n");
44     }
45     return 0;
46 }
View Code

 

posted on 2015-09-17 23:50  改写历史,倾尽天下  阅读(194)  评论(0编辑  收藏  举报

导航