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
");
 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
",flag );
 87 
 88         if ( flag )
 89         {
 90                 printf("No
");
 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
",flag );
108 
109         if ( flag == 1 )
110         {
111             printf("Yes
");
112         }
113         else
114         {
115             printf("No
");
116         }
117 
118     }
119     return 0;
120 }
原文地址:https://www.cnblogs.com/wikioibai/p/4439101.html