HDU 1272 小希的迷宫 并查集

本文介绍如何使用并查集判断一个迷宫是否存在回路,并提供了代码实现。通过输入点之间的连接信息,判断是否形成环状路径,进而确定迷宫是否连通。

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

题意:

  要你判断是不是一个迷宫,条件是每两个点之间只能有一条边相连。

 

坑爹:

  判断有无回路。

 

解法:

  输入的时候判断这两个点的father值相不相等,如果相等的话就代表原来这两个点就是想通的,如果在进行Union的话就会出现环。

 

View Code
  1 #include<iostream>
  2 using namespace std;
  3 
  4 const int MAXN =  100000 + 10 ;
  5 int flag[MAXN];
  6 int father[MAXN];
  7 int rank[MAXN];
  8 
  9 void Make_Set(int x)
 10 {
 11     father[x] = x ;
 12     rank[x] = 0 ;
 13 }
 14 
 15 int find_root(int x)
 16 {
 17     if(father[x] == x)
 18     {
 19         return x;
 20     }
 21     else
 22     {
 23         father[x] = find_root(father[x]);
 24     }
 25 }
 26 
 27 void Union(int a,int b)
 28 {
 29     int roota;
 30     int rootb;
 31     roota = find_root(a) ;
 32     rootb = find_root(b) ;
 33     
 34     if(roota == rootb )
 35     {
 36         return;
 37     }
 38     
 39     if(rank[roota] > rank[rootb] )
 40     {
 41         father[rootb] = roota;
 42     }
 43     else if(rank[roota] < rank[rootb] )
 44     {
 45         father[roota] = rootb;
 46     }
 47     else
 48     {
 49         father[roota] = rootb;
 50         rank[rootb] ++;
 51     }
 52 }
 53 
 54 
 55 int main()
 56 {
 57     int n;
 58     int m;
 59     while(cin>>n>>m)
 60     {
 61         memset(flag,0,sizeof(flag));
 62         if(m == -1 && n == -1 )
 63         {
 64             break;
 65         }
 66         if(m == 0 && n == 0)
 67         {
 68             cout<<"Yes"<<endl;
 69         }
 70         for(int i = 1 ; i < MAXN ; i ++ )
 71         {
 72             Make_Set(i);
 73         }
 74         Union(n,m);
 75         flag[n] = 1 ;
 76         flag[m] = 1 ;
 77         int a;
 78         int b;
 79         int count = 0;
 80         
 81         while(cin>>a>>b,a+b)
 82         {
 83             flag[a] = 1;
 84             flag[b] = 1;
 85             if( find_root(a) == find_root(b) )
 86             {
 87                 count = 1;
 88             }
 89             else
 90             {
 91                 Union(a,b);
 92             }
 93         }
 94         if(count)
 95         {
 96             cout<<"No"<<endl;
 97         }
 98         else
 99         {
100     
101             
102             int count1 = 0;
103             for(i = 1 ; i < MAXN ; i++ )
104             {
105                 if(father[i] == i && flag[i] == 1)
106                 {
107                     count1 ++;
108                 }
109             }
110             
111             if(count1 == 1)
112             {
113                 cout<<"Yes"<<endl;
114             }
115             else
116             {
117                 cout<<"No"<<endl;
118             }
119         }
120     }
121     return 0;
122 }

 

转载于:https://www.cnblogs.com/pcpcpc/archive/2012/09/03/2669397.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值