码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1272 小希的迷宫

时间:2015-07-29 21:24:17      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:

小希的迷宫

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


Problem Description
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。
技术分享
 

Input
输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
整个文件以两个-1结尾。
 

Output
对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"Yes",否则输出"No"。
 

Sample Input
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
 

Sample Output
Yes Yes No
 

Author
Gardon
 

Source
 
 

思路:

 
       首先我们需要知道,什么情况下满足小希的想法,什么情况下不满足小希的想法,然后我们要好好想想输入数据,什么时候全部结束,什么时候本次输入结束,准备输出结果。
       我们现在来逐个来进行解答:满足小希的想法必须只能有一个根,并且不能有环;当输入两个-1 的时候循环结束,当输入两个0的时候本次循环结束,输出结果,但是,当在刚开始的时候就输入两个0,直接输出Yes,别问为什么,这是这个题的漏洞,别再抠这一点了,这一点坑了不少的人!
    这道题的精髓之处就是判断根的个数和是否是环!

 

代码:

 

 #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;
}


 

 
 

版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 1272 小希的迷宫

标签:

原文地址:http://blog.csdn.net/dxx_111/article/details/47133191

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!