zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    二分法模板
    二分答案模板
    51nod 1010 只包含因子2 3 5的数
    三次握手和四次挥手(面试必问)
    TCP协议和UDP协议
    纯CSS3画出小黄人并实现动画效果
    正则表达式里字符串”不包含”匹配技巧
    12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
    使用jTopo给Html5 Canva中绘制的元素添加鼠标事件_html5教程技巧
    程序猿们,快用Emoji表情写代码吧
  • 原文地址:https://www.cnblogs.com/wikioibai/p/4439101.html
Copyright © 2011-2022 走看看