產生冠軍
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 23900 Accepted Submission(s): 10775
球賽的規則如下:
如果A打敗了B,B又打敗了C,而A與C之間沒有進行過比賽,那麼就認定,A一定能打敗C。
如果A打敗了B,B又打敗了C,而且,C又打敗了A,那麼A、B、C三者都不可能成爲冠軍。
根據這個規則,無需循環較量,或許就能確定冠軍。你的任務就是面對一羣比賽選手,在經過了若干場撕殺之後,確定是否已經實際上產生了冠軍。
3 Alice Bob Smith John Alice Smith 5 a c c d d e b e a d 0
Yes No
除了通過遍歷所有的關係來找出是否有一個人可以根據題目要求的方法打敗所有人外,可以將這些關係抽象爲一張有向圖,如果有冠軍,那麼一定可以從該冠軍出發找到到其他所有頂點的一條路徑,那麼如果該圖的入度爲0的頂點只有一個的話,就一定存在冠軍。對於圖是否存在環,如果存在局部環,那麼只要有一個環外面的人擊敗了環中的任意一個人,那麼他就可以擊敗這個環上的所有人。如果整個圖是一個環,那麼就不存在入度爲0的點,則不存在冠軍。同理,如果存在多個連通分量也可以同樣的分析。
#include <iostream>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
#include <typeinfo>
#include <cstring>
using namespace std;
typedef long long ll;
std::map<string, int> ans;
std::map<string, int>::iterator it;
int main(int argc, char const *argv[])
{
int n;
while(cin>>n&&n){
string a,b;
ans.clear();
for(int i=0;i<n;i++){
cin>>a>>b;
if(ans.find(b)!=ans.end()) ans[b]++;
else ans[b]=1;
if(ans.find(a)==ans.end()) ans[a]=0;
}
int cnt=0;
for(it=ans.begin();it!=ans.end();++it){
if(it->second==0) cnt++;
}
cout<<(cnt==1?"Yes":"No")<<endl;
}
return 0;
}