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
題目: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