您的位置:首页 > 其它

HDU 2094 产生冠军(STL & 拓扑)

2016-11-25 22:41 330 查看
原题链接:Here!


分析:
一群人比赛,然后给出n个二元关系<winner,loser>,产生冠军的情况只有一种 —— 有且只有一个人从没败过。至于为什么是这样,最后再讲。
根据分析,我们需要记录每个人失败的次数 loser[] ,又因为每次输入的都是两个字符串,所以采用容器map<string,int> loser,然后又得记下来比赛人的"姓名",因为一些姓名会重复出现,利用set的互异性就能简单的找到所有人的"姓名",所以用了set<string>
name。可以自行百度STL map和set容器用法。


CODE:

根据上面的分析就可以很简单的写出程序了。
#include<iostream>
#include<string>
#include<map>
#include<set>
using namespace std;

const int maxn = 100+2;
int n;
map< string,int > 	loser;
set< string > 		name;
int main(){
while(scanf("%d",&n)!=EOF && n){
loser.clear();
name.clear();

string win,los;
for(int i=1;i<=n;i++){
cin>> win;
cin>> los;
name.insert(win);	name.insert(los);
loser[los]++;
}
int cnt=0;				// cnt记录有几个人从未败过
set< string >::iterator it; 		// 定义前向迭代器
for(it=name.begin();it!=name.end();it++){
string t=*it;
if(loser[t]==0)	cnt++;
}
if(cnt==1)	cout<<"Yes"<<endl;
else		cout<<"No"<<endl;
}
return 0;
}

至于为什么产生冠军的情况只有一种 —— 有且只有一个人从没败过。这需要了解过拓扑排序知识才能迅速理解,我们把二元关系<winner,loser>看作成一个有向边(winner,loser),则所有二元关系就构成了一个有向图,因为这个题不会出现A败给B,B败给C,C败给A这种情况,所以就构成了一个DAG(有向无环图)。

例如:
3

Alice Bob

Smith John

Alice Smith
DAG:



5

a c

c d

d e

b e

a d
DAG:



观察图可以发现,所有的winner均未败过,loser[  ]=0,但是如果有一场比赛中存在多个"winner",那这个比赛是没有冠军的。所以能够产生冠军的条件是有且只有一个人从没败过。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: