- 原题链接: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",那这个比赛是没有冠军的。所以能够产生冠军的条件是有且只有一个人从没败过。
HDU 2094 产生冠军(STL & 拓扑)
最新推荐文章于 2020-03-05 09:23:02 发布