HDU 1272 小希的迷宫(并查集)
题目大意:
题目说的是,给你一些边的关系来构成一棵树,然后让你求出这在这个生成树中是否有环,也就是说,对于树上的任意一个节点,是否存在从这个点到其余节点的第二条路径。
解题思路:
裸裸的并查集,我们只需要将每次输入的边的关系进行一个合并,然后用book[]数组去标记哪些点已经在这个生成树出现过了,因为我们知道在构树的过程中,我们预先并不能知道树上的节点编号是否连续,树上的节点编号的最大值和最小值分别为多少的问题。最后,扫一遍f[]数组,把f[i]==i并且book[i]==1的点有一个的话,那么我就出Yes。
还有一种情况就是说,我们再输入的过程中,如果发现了getf(a)==getf(b)的值,那么我们直接返回Yes了,因为这个时候就和最小生成树中的判断是否联通的问题很相似了。
代码:
1 # include<cstdio> 2 # include<iostream> 3 # include<cstring> 4 5 using namespace std; 6 7 # define MAX 100000+10 8 9 int f[MAX]; 10 int book[MAX]; 11 12 int getf ( int v ) 13 { 14 if( f[v]==v ) 15 { 16 return v; 17 } 18 else 19 { 20 f[v] = getf(f[v]); 21 return f[v]; 22 } 23 } 24 25 void merge ( int v,int u ) 26 { 27 int t1 = getf(v); 28 int t2 = getf(u); 29 if ( t1!=t2 ) 30 { 31 f[t2] = t1; 32 } 33 } 34 35 int main(void) 36 { 37 int a,b; 38 while ( scanf("%d %d",&a,&b) ) 39 { 40 //这仅仅是第一组数据 41 if ( a==-1&&b==-1 ) 42 break; 43 if ( a==0&&b==0 ) 44 { 45 printf("Yes\n"); 46 continue; 47 } 48 memset(book,0,sizeof(book)); 49 book[a] = book[b] = 1; 50 int _min, _max; 51 if ( a>b ) 52 { 53 _min = b, _max = a; 54 } 55 else 56 { 57 _min = a, _max = b; 58 } 59 60 for ( int i = 1;i <= 100000;i++ ) 61 { 62 f[i] = i; 63 } 64 int flag = 0; 65 merge(a,b); 66 while ( scanf("%d %d",&a,&b) ) 67 { 68 if ( a==0&&b==0 ) 69 break; 70 book[a] = book[b] = 1; 71 _max = max(_max,a); 72 _max = max(_max,b); 73 _min = min(_min,a); 74 _min = min(_min,b); 75 // cout<<_min<<" "<<_max<<" "<<endl; 76 if ( getf(a)==getf(b) ) 77 { 78 flag = 1; 79 } 80 else 81 { 82 merge(a,b); 83 } 84 85 } 86 // printf("flag = %d\n",flag ); 87 88 if ( flag ) 89 { 90 printf("No\n"); 91 continue; 92 } 93 /* for ( int i = _min;i <= _max;i++ ) 94 printf("%d ",f[i] ); 95 cout<<endl; 96 for ( int i = _min;i <= _max;i++ ) 97 printf("%d ",book[i]); 98 cout<<endl; 99 */ 100 for ( int i = _min;i <= _max;i++ ) 101 { 102 if ( book[i]==1&&f[i]==i ) 103 { 104 flag++; 105 } 106 } 107 // printf("flag = %d\n",flag ); 108 109 if ( flag == 1 ) 110 { 111 printf("Yes\n"); 112 } 113 else 114 { 115 printf("No\n"); 116 } 117 118 } 119 return 0; 120 }