Loading

HDU 1272 小希的迷宫(简单并查集)

描述

传送门:我是传送门

上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。 

迷宫

输入

输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
整个文件以两个-1结尾。

输出

对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出”Yes”,否则输出”No”。

样例

输入

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

思路

相比前边写的几个题来说这道题简单太多了

只需要在每次新加入两个点的时候判断这两个点是否是不连通的,如果联通的话说明出现环了,肯定不满足题目要求

然后在最后再跑一遍是否是只存在一个图(即所有点的父节点在同一集合)

一开始用set提交上去TLE了,常数太大了吗?

代码

  1 /*
  2  * ==============================================
  3  *
  4  *       Filename:  M.cpp
  5  *
  6  *           Link:  http://acm.hdu.edu.cn/showproblem.php?pid=1272
  7  *
  8  *        Version:  1.0
  9  *        Created:  2018/09/24 02时13分45秒
 10  *       Revision:  none
 11  *       Compiler:  g++
 12  *
 13  *         Author:  杜宁元 (https://duny31030.top/), duny31030@126.com
 14  *   Organization:  QLU_浪在ACM
 15  *
 16  * ==============================================
 17  */
 18 #include <bits/stdc++.h>
 19 using namespace std;
 20 #define clr(a, x) memset(a, x, sizeof(a))
 21 #define rep(i,a,n) for(int i=a;i<=n;i++)
 22 #define pre(i,a,n) for(int i=n;i>=a;i--)
 23 #define ll long long
 24 #define max3(a,b,c) fmax(a,fmax(b,c))
 25 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 26 const double eps = 1e-6;
 27 const int INF = 0x3f3f3f3f;
 28 const int mod = 1e9 + 7;
 29 const int N = 100009;
 30 int f[N];
 31 // set<int> s;
 32 int find(int x)
 33 {
 34     // int t = f[x];
 35     if(f[x] != x)
 36     {
 37         f[x] = find(f[x]);
 38     }
 39     return f[x];
 40 }
 41 
 42 bool vis[N];
 43 void init()
 44 {
 45     // s.clear();
 46 
 47     rep(i,0,N-1)
 48     {
 49         f[i] = i;
 50         vis[i] = 0;
 51     }
 52 }
 53 
 54 int main()
 55 {
 56     ios
 57 #ifdef ONLINE_JUDGE 
 58 #else 
 59         freopen("in.txt","r",stdin);
 60     // freopen("out.txt","w",stdout); 
 61 #endif
 62     int x,y;
 63     init();
 64     int flag = 0;
 65     while(scanf("%d %d",&x,&y)!= EOF)
 66     {
 67         if(x == y && x < 1)
 68         {
 69             if(x == -1)
 70                 break;
 71             else 
 72             {   
 73                 if(flag)
 74                 {
 75                     printf("No\n");
 76                 }
 77                 else 
 78                 {
 79                     int tmp = -1;
 80                     for(int i = 0;i < N;i++)
 81                     {
 82                         if(!vis[i]) continue;
 83                         if(tmp == -1)    tmp = find(i);
 84                         if(tmp != find(i))
 85                         {
 86                             flag = 1;
 87                             break;
 88                         }
 89                     }
 90 
 91                     if(flag)
 92                         printf("No\n");
 93                     else 
 94                         printf("Yes\n");
 95                 }
 96                 init();
 97                 flag = 0;
 98                 continue;
 99             }
100         }
101         vis[x] = 1;
102         vis[y] = 1;
103         int fx = find(x);
104         int fy = find(y);
105         if(fx == fy)
106         {
107             flag = 1;
108         }
109         else 
110         {
111             f[fx] = fy;
112         }
113     }
114     fclose(stdin);
115     // fclose(stdout);
116     return 0;
117 }

 

posted @ 2021-01-20 21:07  Yiduuannng  阅读(87)  评论(0编辑  收藏  举报