HDU_1272_小希的迷宫

HDU 1272


思路:注意迷宫里元素的编号并不一定是连续的而且也不一定是从1开始,故在输入时用一个set保存元素编号,并查集时遍历set中元素,最终判断是不是只有一个集合即可(途中要判断是不是有多条路,具体见代码)。



#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <deque>
#include <queue>
#include <vector>
#include <algorithm>
#include <functional>


#define debug(x) cout << "--------------> " << x << endl


using namespace std;


const double PI = acos(-1.0);
const double eps = 1e-10;
const long long INF = 0x7fffffff;
const long long MOD = 1000000007;
const int MAXN = 100000 + 7;
int pre[MAXN];
int u[MAXN], v[MAXN];


int findRootNode(int x)
{
        int r = x;
        while(pre[r] != r)
                r = pre[r];


        int i = x;


        while(i != r)
        {
                int j = pre[i];
                pre[i] = r;
                i = j;
        }


        return r;
}


bool setMerge(int x, int y)                      //判断能否合并,并且合并
{
        int root_x, root_y;
        root_x = findRootNode(x);
        root_y = findRootNode(y);


        if(root_x < root_y)
                pre[root_y] = root_x;
        else
                pre[root_x] = root_y;
        return root_x == root_y;
}


int main()
{
     int a, b;
     int ans = 0;
     int index = 0;
     set<int> s;                                 //保存输入的元素编号
     bool flag = false;
     for(int i = 0; i < MAXN; ++i)
        pre[i] = i;
     while(scanf("%d%d", &a, &b), a != -1 && b != -1)
     {
             if(a == 0 && b == 0)
             {
                for(int i = 0; i < index; ++i)
                {
                        if(!setMerge(u[i], v[i])){}      //不能合并,即v[i]、u[i]有相同祖先,不止一条条路
                        else
                        {
                                flag = true;
                                break;
                        }
                }
                if(flag)
                        printf("No\n");
                else
                {
                        for(set<int>::iterator it = s.begin(); it != s.end(); ++it)   //对set中元素遍历
                        {
                                if(pre[*it] == *it)
                                {
                                        ans++;
                                }
                        }
                        if(ans > 1)
                                printf("No\n");
                        else
                                printf("Yes\n");
                }
                for(int i = 1; i < MAXN; ++i)
                        pre[i] = i;
                ans = 0;
                flag = false;
                index = 0;
                s.clear();


             }
             else
             {
                u[index] = a;
                v[index] = b;
                index++;
                s.insert(a);
                s.insert(b);
             }
     }
     return 0;
}

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值