程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> ACM-並查集之小希的迷宮——hdu1272

ACM-並查集之小希的迷宮——hdu1272

編輯:C++入門知識

***************************************轉載請注明出處:http://blog.csdn.net/lttree***************************************



小希的迷宮

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


Problem Description 上次Gardon的迷宮城堡小希玩了很久(見Problem B),現在她也想設計一個迷宮讓Gardon來走。但是她設計迷宮的思路不一樣,首先她認為所有的通道都應該是雙向連通的,就是說如果有一個通道連通了房間A和B,那麼既可以通過它從房間A走到房間B,也可以通過它從房間B走到房間A,為了提高難度,小希希望任意兩個房間有且僅有一條路徑可以相通(除非走了回頭路)。小希現在把她的設計圖給你,讓你幫忙判斷她的設計圖是否符合她的設計思路。比如下面的例子,前兩個是符合條件的,但是最後一個卻有兩種方法從5到達8。
IDC94c6ytcTV+8r9ttTB0LHto6yx7cq+wcvSu8z1zai1wMGsvdO1xMG9uPa3v7zktcSx4LrFoaO3v7zktcSx4LrF1sHJ2c6qMaOsx9Kyu7Osuf0xMDAwMDCho8O/wb3X6cr9vt3Wrrzk09DSu7j2v9XQ0KGjIDxicj4K1fu49s7EvP7S1MG9uPYtMb3hzrKhozxicj4KCgogCjxicj4KCk91dHB1dAoKttTT2srkyOu1xMO/0rvX6cr9vt2jrMrks/a99rD8wKjSu9DQoaPI57n7uMPD1Lmst/u6z9Chz6O1xMu8wrejrMTHw7TK5LP2"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 HDU 2006-4 Programming Contest

題目:http://acm.hdu.edu.cn/showproblem.php?pid=1272


漢語題目,不多說。

並查集來解決,判斷要合並的兩個集合原來是否屬於同一集合。

但是,還有幾點要注意:

1. 不止要判斷原來是否屬於同一集合,還要判斷是否有孤立的點。

2.如果沒有數據,直接輸入0 0,應該輸出Yes

3.所有的點並不是連續的,根據例1 可以知道,最小的點是2,最大的點是8,但是沒有7這個點。


恩,注意上述幾點,就可以完成了。


/*******************************************  
********************************************  
*           Author:Tree                    *  
*    From :  blog.csdn.net/lttree          *  
*      Title : 小希的迷宮                  *  
*    Source: hdu 1272                      *  
*      Hint :  並查集                      *  
********************************************  
*******************************************/    

#include 
#include 

int father[100010];
bool isright,vis[100010];

void Init( void )
{
	for( int i=1;i<100010;++i )
		father[i]=i;
}
int Find( int x )
{
	while( x!=father[x] )
	{
		x=father[x];
	}
	return x;
}
// 合並函數
void Combine(int a,int b)
{
	int temp_a,temp_b;
	temp_a=Find(a);
	temp_b=Find(b);
	if( temp_a!=temp_b )
		father[temp_a]=temp_b;
	else	isright=false;		// 如果本來屬於同一集合,不屬於小希迷宮
}

// 判斷 是否只有一個集合
bool judge( int Min,int Max )
{
	int i,js=0;
	for( i=Min;i<=Max;++i )
		if( vis[i] && father[i]==i )
			++js;
	if( js==1 )	return true;
	return false;
}

int main()
{
	int a,b,Max,Min;
	
	// 初始化
	Init();
	isright=true;
	Min=0x3f3f3f3f;
	Max=-1;
	memset(vis,0,sizeof(vis));

	while( scanf("%d%d",&a,&b) && (a!=-1||b!=-1) )
	{
		if( !a || !b )
		{
			if( isright )
			{
				// Max!=-1 必須有,防止上來就輸入0 0
				if( judge(Min,Max)==0 && Max!=-1 )
					printf("No\n");
				else	printf("Yes\n");
			}
			else	printf("No\n");
			
			// 完成一組數據,初始化一下
			Init();
			isright=true;
			Max=-1;
			Min=0x3f3f3f3f;
			memset(vis,0,sizeof(vis));
			continue;
		}
		
		//記錄哪些點存在
		vis[a]=vis[b]=1;
		// 找最小值與最大值
		Max=a>Max?a:Max;
		Max=b>Max?b:Max;
		Min=a


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved