题目的意思,如题。很容易明白。
解决的方法就是拓扑排序,就可以很容易的解决了。
每输入一对选手,判断两个选手是否出现过,没有出现过,新建一个头结点,加入到邻接表中,更新结点的入度。
最后判断是否存在一个结点的入度为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;
}