原文链接:http://www.cnblogs.com/FCWORLD/archive/2011/04/07/2007468.html
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
题目大意:冠军要与每个人直接或间接的打上一场并获得胜利。即一场未曾输过的人。要保证有且仅有一个。
如果冠军存在,输出Yes,否则输出No。
解题思路:冠军要和每个人直接或间接的打上一场并获得胜利,所以冠军一定是唯一一个入度为0的点。输过比赛的人入度一定大于等于1。所以只要找入度为0的点的个数就可以了。如果个数大于一,则不存在冠军,等于1即存在。
另外一点需要注意名字的存法,可以用map来解决。
Code:
#include<iostream>
#include<queue>
#include<vector>
#include<map>
#include<cstring>
using namespace std;
const int maxn = 1005;
int n,in[maxn];
string s1,s2;
vector<int>v[maxn];//用来存储两者间的关系,该题表示存储输给选手a的选手
int main(){
while(cin>>n&&n){
int p=1;
map<string,int>m;//存储每个选手
memset(in,0,sizeof(in));//清空in
while(n--){
cin>>s1>>s2;//选手a和选手b,是变化的
if(m[s1]==0) m[s1]=p++;//按每个选手名字出现的顺序,从1开始从小到大进行赋值
if(m[s2]==0) m[s2]=p++;
int x,y;
x=m[s1],y=m[s2];//x表示选手a的顺序,用x来表示选手a
in[y]++;//输的人增加入度
v[x].push_back(y);//存储输给选手x(a)的选手
}
queue<int>q;
p--;//p--后表示选手人数
for(int i=1;i<=p;i++){
if(in[i]==0){
q.push(i);//将入度为0的点进行入队
}
}
int flag=q.size();//flag表示队列大小
//cout<<flag<<endl;
if(flag==1)cout<<"Yes
";
else cout<<"No
";
for(int i=1;i<=p;i++) v[i].clear();//因为一开始并不知道选手的人数,所以只能在一个样例结尾的时候对v进行清空
}
return 0;
}