产生冠军(王道)

题目描述:

有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。
球赛的规则如下:
如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。

输入:

输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果,比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。如果n为0,则表示输入结束。

输出:

对于每个选手群,若你判断出产生了冠军,则在一行中输出“Yes”,否则在一行中输出“No”。

样例输入:
3
Alice Bob
Smith John
Alice Smith
5
a c
c d
d e
b e
a d
0
样例输出:
Yes
No
 1 #include <iostream>
 2 #include<vector>
 3 #include<map>//要使用map,必须包含此头文件
 4 #include<string>
 5 #include<queue>
 6 using namespace std;
 7 
 8 map<string,int> M;//定义完成从string到int映射的map
 9 int in[2002];
10 int main()
11 {
12     int n;
13     while(scanf("%d",&n)!=EOF){
14         for(int i=0;i<2*n;i++)//n组胜负关系,至多存在n个队伍
15             in[i]=0;//初始化入度
16         M.clear();//清空一个map
17         int idx=0;//下一个被映射的数字
18         for(int i=0;i<n;i++){
19             char str1[50],str2[50];
20             scanf("%s%s",str1,str2);
21             string a=str1,b=str2;
22             int idxa,idxb;
23             if(M.find(a)==M.end()){//map中没有对a的映射
24                 idxa=idx;
25                 M[a]=idx;//设定其映射为idx
26                 idx++;//递增idx
27             }
28             else
29                 idxa=M[a];//直接读出该映射
30             if(M.find(b)==M.end()){
31                 idxb=idx;
32                 M[b]=idx;
33                 idx++;
34             }
35             else
36                 idxb=M[b];
37             in[idxb]++;//b的入度递增
38         }
39         int cnt=0;
40         for(int i=0;i<idx;i++){//统计入度为0的个数
41             if(in[i]==0)
42                 cnt++;
43         }
44         puts(cnt==1?"YES":"NO");//入度为0的点唯一说明有冠军
45     }
46     return 0;
47 }

 

posted @ 2018-03-25 10:01  Shaw_喆宇  阅读(475)  评论(0编辑  收藏  举报