产生冠军(set,map,拓扑结构三种方法)

产生冠军

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10983    Accepted Submission(s): 5088


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

 

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

 

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

 

Sample Input
3 Alice Bob Smith John Alice Smith 5 a c c d d e b e a d 0
 

 

Sample Output
Yes No
set 题解:总人数减去失败的人等于一 ,也就是只有一个人没失败过;handsome借此总结了一条名言:打败最吊的人,你就最吊了,哪怕这个吊人赢得再多;一组数据就可以验证此句名言:
a b
a c
a d
a x
g a
答案为6-5=1;g最吊;;;;;;
代码:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<string>
 4 #include<set>
 5 using namespace std;
 6 int main(){int n;string a,b;
 7     while(scanf("%d",&n),n){
 8         set<string>tot;
 9         set<string>looser;
10         while(n--)cin>>a>>b,tot.insert(a),tot.insert(b),looser.insert(b);
11         if(tot.size()-looser.size()==1)puts("Yes");
12         else puts("No"); 
13     }
14     return 0;
15 }
View Code

 map题解:胜利的每次+1,失败的直接赋值无穷小;最后判断为正的个数是否为一;

代码:

 1 #include<iostream>
 2 #include<map>
 3 #include<string>
 4 #define INF -0xffff
 5 using namespace std;
 6 int main(){
 7     map<string,int>player;//注意由于下面是player[a],a,b是字符串,所以string在前; 
 8     map<string,int>::iterator iter;//
 9     string a,b;int n,flot;
10     while(scanf("%d",&n),n){player.clear();flot=0;
11         while(n--)cin>>a>>b,player[a]++,player[b]=INF;
12         for(iter=player.begin();iter!=player.end();iter++){
13             if(iter->second>=1)flot++;
14         }
15         if(flot==1)puts("Yes");
16         else puts("No");
17     }
18     return 0;
19 } 
View Code

 拓扑结构+邻接表:

 1 #include<string.h>
 2 #include<queue>
 3 #include<map>
 4 #include<string>
 5 #include<stdio.h>
 6 using namespace std;
 7 const int MAXN=1010;
 8 int que[MAXN];
 9 struct Node{
10     int to,next;
11 };
12 Node edg[MAXN];
13 int head[MAXN];
14 map<string,int>mp;
15 int k;
16 priority_queue<int,vector<int>,greater<int> >dl;
17 void topu(){
18     for(int i=0;i<k;i++){
19         if(!que[i])dl.push(i);
20     }
21     if(dl.size()==1)puts("Yes");
22     else puts("No");
23 }
24 void initial(){
25     memset(head,-1,sizeof(head));
26     memset(que,0,sizeof(que));
27     mp.clear();
28     while(!dl.empty())dl.pop();
29     k=0;
30 }
31 int main(){
32     int n;
33     char s1[110],s2[110];
34     while(~scanf("%d",&n),n){
35             initial();
36         for(int i=0;i<n;i++){
37             scanf("%s%s",s1,s2);
38             if(!mp.count(s1))mp[s1]=k++;
39             if(!mp.count(s2))mp[s2]=k++;
40             edg[i].to=mp[s2];
41             edg[i].next=head[mp[s1]];
42             head[mp[s1]]=i;
43             que[mp[s2]]++;
44         }
45         topu();
46     }
47 return 0;
48 }
原文地址:https://www.cnblogs.com/handsomecui/p/4680231.html