zoukankan      html  css  js  c++  java
  • HDU 1272 小希的迷宫(并查集)

    题解:

    首先,init,find,union操作都是模版,多敲几遍,在记记,就没问题了。

    然后,本题就是多了一个flag数组,记录数据是否出现过,最后记录最小,和最大,遍历一般他们的父亲,只有一个就是yes,否则no。

    但又2个要注意:①当输入只有0 0的时候是输出yes,(题目里也没说啊,其实这我也不知道为啥要是yes)

    ②要判断有内环的情况,具体看代码注释。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5+5;
    const double eps = 1e-7;
    
    int rankk[maxn], fa[maxn], flag[maxn];
    ///基本上是模板
    void Init(int x)
    {
        for(int i=0; i<=x; i++)
        {
            fa[i] = i;
            flag[i] = rankk[i] = 0;
        }
    }
    
    int Find(int x)
    {
        if(fa[x] != x)
            fa[x] = Find(fa[x]);
        return fa[x];
    }
    
    void Union(int x, int y)
    {
        int fx = Find(x);
        int fy = Find(y);
        if(fx == fy)
            return;
        if(rankk[fx] > rankk[fy])
            fa[fy] = fx;
        else
        {
            fa[fx] = fy;
            if(rankk[fx] == rankk[fy])
                rankk[fy]++;
        }
    }
    
    int main()
    {
        int a, b;
        while(cin>>a>>b)
        {
            bool ok = 0;
            int cnt = 0;
            if(a==-1 && b==-1)
                break;
            ///当a==0和b==0的时候也是符合条件的
            if(a==0 && b==0)
            {
                puts("Yes");
                continue;
            }
            Init(maxn);
            int Max = -99999999, Min = 999999999;
            while(a!=0 && b!=0)
            {
    
                //找最大和最小值, 循环一遍,只有一个父亲就yes了 但有的点没有涉及,所以要开flag数组记录
                //最后是这个点要出现过,并遍历所有出现过的点,父亲都只有一个才yes
                Max = max(max(a,b),Max);
                Min = min(min(a,b),Min);
                flag[a] = flag[b] = 1;
                if(Find(a) == Find(b))
                {
                    ok = 1;//这判断的是环的时候的情况
    //                puts("内环的时候的情况");
                }
                else
                    Union(a, b);
                cin>>a>>b;
            }
            if(ok)
                puts("No");
            else
            {
                for(int i=Min; i<=Max; i++)
                    if(flag[i] && fa[i]==i)//这个判断就是代表只有一个在原点,也就是一个父亲连着所有儿子
                        cnt++;
                if(cnt == 1)
                    puts("Yes");
                else
                    puts("No");
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    BZOJ 1823: [JSOI2010]满汉全席 [2-SAT]
    POJ 3683 Priest John's Busiest Day[2-SAT 构造解]
    Centos出现-bash: unzip: command not found的解决办法
    物理cpu与逻辑cpu概述
    如何正确查看Linux机器内存使用情况
    connections java.net.BindException: Address already in use_解决方案
    Linux查看端口、进程情况及kill进程
    linux如何查看端口被哪个进程占用?
    如何正确查看Linux机器内存使用情况
    TPS和事务响应时间的关系
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5520980.html
Copyright © 2011-2022 走看看