题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2094
题解:转化成图,a->b,b->c......能产生冠军,存在唯一一个点入度为0.
#include <stdio.h>
#include <string.h>
int father[2001],degree[2001],tot;
char str[2001][20];
int check(char *s)
{
int i;
for(i=0;i<tot;++i)
{
if(strcmp(str[i],s)==0)
return i;
}
strcpy(str[tot++],s);
return (tot-1);
}
int find(int x)
{
while(x!=father[x])
x=father[x];
return father[x];
}
int main()
{
int n,edge,i,sx,sy,ans;
char s1[20],s2[20];
while (scanf("%d",&n)&&n)
{
tot=0;
edge=0;
for(i=0;i<2001;++i)
{
father[i]=i;
degree[i]=0;
}
for(i=0;i<n;++i)
{
scanf("%s %s",s1,s2);
sx=check(s1);
sy=check(s2);
degree[sy]++;//s1胜s2,s2入度++
sx=find(sx);
sy=find(sy);
if(sx!=sy)
{
father[sx]=sy;
edge++;//记录边数
}
}
if(edge!=tot-1)
{//边数不等于顶点数-1,不是一个集合,不能确定是否产生冠军
printf("No\n");
continue;
}
ans=0;
for(i=0;i<tot;++i)
{
if(degree[i]==0)
ans++;//只有一个顶点入度为0,产生冠军
}
if(ans==1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}