题目的意思,如题。很容易明白。
解决的方法就是拓扑排序,就可以很容易的解决了。
每输入一对选手,判断两个选手是否出现过,没有出现过,新建一个头结点,加入到邻接表中,更新结点的入度。
最后判断是否存在一个结点的入度为0,有,则Yes,否则No。
我用的是STL中的list容器来创建的邻接表。
下面的是 AC的代码:
#include <iostream> #include <list> #include <cstring> using namespace std; class data //结点的结构体 { public: int indegree; int point; char str[100]; }; list <data> List[2000]; //链表数组,存在多个人 int main() { int n, i, j, k; char s1[100], s2[100]; data temp; while(cin >> n && n) { for(i = 0; i < 2000; i++) //清空各个链表 List[i].clear(); k = 0; for(i = 0; i < n; i++) { cin >> s1 >> s2; int flag = 0, tag = 0, a, b; a = b = -1; for(j = 0; j < k; j++) { if(strcmp(List[j].front().str, s1) == 0) //判断第一个人是否出现过 { a = j; //标记在链表数组的下标 flag = 1; } if(strcmp(List[j].front().str, s2) == 0) //判断第二个人是否出现过 { b = j; //同上 tag = 1;; } } if(!flag) //没存在,新建一个,扩大数组的大小 { strcpy(temp.str, s1); temp.indegree = 0; temp.point = -1; List[k].insert(List[k].end(), temp); k++; } if(!tag) //同上 { strcpy(temp.str, s2); temp.indegree = 0; temp.point = -1; List[k].insert(List[k].end(), temp); k++; } if(flag && !tag) //第一个出现过,第二个没有 { List[k - 1].front().indegree++; //更新入度 strcpy(temp.str, s2); temp.indegree = -1; temp.point = k - 1; List[a].insert(List[a].end(), temp); } else if(!flag && tag) //第一个没出现,第二个出现过 { List[b].front().indegree++; strcpy(temp.str, s2); temp.indegree = -1; temp.point = b; List[k - 1].insert(List[k - 1].end(), temp); } else if(flag && tag) //都出现过 { List[b].front().indegree++; strcpy(temp.str, s2); temp.indegree = -1; temp.point = b; List[a].insert(List[a].end(), temp); } else if(!flag && !tag) //都没出现过 { List[k - 1].front().indegree++; strcpy(temp.str, s2); temp.indegree = -1; temp.point = k - 1; List[k - 2].insert(List[k - 2].end(), temp); } } int ans = 0; for(i = 0; i < k; i++) { if(List[i].front().indegree == 0 && !List[i].empty()) ans++; } if(ans == 1) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/qq_25425023/article/details/47030809