Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 34543 Accepted Submission(s): 10573

6 8 5 3 5 2 6 4 5 6 0 0 8 1 7 3 6 2 8 9 7 5 7 4 7 8 7 6 0 0 3 8 6 8 6 4 5 3 5 6 5 2 0 0 -1 -1
Yes Yes No
#include <stdio.h>
#define MAX 100005
int pre[MAX];//代表父节点
int vis[MAX];//标记是否输入
int flag;//标记是否符合条件
int find(int x)//找根节点并且压缩路径
{
int r;
r=x;
while(r!=pre[r])
r=pre[r];
int i,j;
i=x;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void join(int x,int y)//将不同根节点的数连到一起
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)//如果根节点不同,就将不同根节点的两个数连到一起
pre[fx]=fy;
else//否则说明有相同的根节点,然后还需要将其两个点连起来,所以说明为回路,不满足条件,flag=0;
flag=0;
}
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a==-1&&b==-1)//当输入两个-1时结束输入
break;
if(a==0&&b==0)//当输入两个0时结束本次输入
{
printf("Yes\n");//输出Yes,这一点比较坑,题上没有进行说明,要特别注意!!!
continue;
}
for(int i=1;i<=100005;i++)//建立100005个房间,之间没有路,也就是建立10005个节点
{
pre[i]=i;
vis[i]=0;//标记为0
}
vis[a]=1;vis[b]=1;//输入哪个就标记哪个,因为输入不是连续的,到后面判断有几个根的时候就用到此处的标记了。(只判断输入的数的根有几个)
flag=1;//假设输入满足要求,当不符合要求时,赋值为0
join(a,b);//将a与b的根连到一起 并判断是否成环
while(scanf("%d%d",&a,&b)&&(a||b))//继续输入,并判断是否为0,如果两个都为0,则结束循环!
{
vis[a]=1;//标记输入
vis[b]=1;
join(a,b);
}
int s=0;
for(int i=1;i<100005;i++)//i==pre[i]是i是根节点的充分必要条件!
{
if(i==pre[i]&&vis[i])//vis[i]不能写到for循环判断语句中,因为如果不连续则会使不能判断之后的数据是否是根
s++;//因为输入的数不一定连续,所以只能在输入的数中判断有几个根,没有输入的每个数都是根
if(s>1)//当大于一个根的时候就不满足条件了,所以给flag赋值为0 ,跳出循环
{
flag=0;
break;
}
}
if(flag==1)//flag标记是否满足小希的要求:1代表符合,0代表不符合
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/dxx_111/article/details/47133191