HDU 2094产生冠军

原文链接: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\n";
		else cout<<"No\n";
		for(int i=1;i<=p;i++) v[i].clear();//因为一开始并不知道选手的人数,所以只能在一个样例结尾的时候对v进行清空 
	}
	
	return 0;
}
posted @ 2019-08-07 15:04  voids5  阅读(81)  评论(0编辑  收藏  举报