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 }