zoukankan      html  css  js  c++  java
  • POJ1703 Find them, Catch them (并查集)

    题意:是一个城市有两个帮派Gang Dragon 和 Gang Snake,A a b是询问a和b这两个人是不是一个帮派,D a b是这两个人不在一个帮派 每一次A就输出一次。

    城市有只有3中人,要么属于S,要么属于D,还有一种未知

    这题和奇偶游戏很相似,可以用扩展域并查集,也可以用边带权并查集,感觉扩展域更好写一些

    扩展域:对于每个人x拆成x_d,x_s,分别表示x属于帮派D和帮派S,设x表示它属于帮派D,x+n表示属于S,那么对于每次询问D a b,a和b不同时属于一个集合,我们合并a_d和b_s,a_s和b_d,这说明它们是关联在一起的。

    对于每次查询,我们如果a,b在一个集合中,说明他们属于同一派,如果a+n和b在同一个集合中说明他们不属于同一派,如果这两种都不满足,就是未知

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N = 2e5 + 10;
    int fa[N],t,n,m;
    int get(int x)
    {
        if (fa[x] == x) return x;
        return fa[x] = get(fa[x]);
    }
    void merge(int x, int y)
    {
        fa[get(x)] = get(y);
    }
    bool same(int x, int y)
    {
        return get(x) == get(y);
    }
    int main()
    {
        cin >> t;
        while (t--)
        {
            scanf("%d%d", &n, &m);
            for (int i = 0; i <=2* n; i++)//i表示D,i+n表示s
                fa[i] = i;
            getchar();
            while (m--)
            {
                char op;
                int a, b;
                scanf("%c%d%d", &op, &a, &b);
                getchar();
                if (op == 'D')
                {
                    int a_d = a, a_s = a+n;
                    int b_d = b, b_s = b + n;
                    merge(a_d, b_s);
                    merge(a_s, b_d);
                }
                else
                {
                    if (same(a, b))
                        printf("In the same gang.
    ");
                    else if (same(a + n, b))
                        printf("In different gangs.
    ");
                    else
                        printf("Not sure yet.
    ");
                }
            }
        }
        return 0;
    }

     

    边带权:和奇偶游戏类似,不说了

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N = 2e5 + 10;
    int fa[N],t,n,m,d[N];
    int get(int x)
    {
        if (fa[x] == x) return x;
        int root = get(fa[x]);
        d[x] ^= d[fa[x]];
        return fa[x] = root;
    }
    void merge(int x, int y)
    {
        fa[get(x)] = get(y);
    }
    bool same(int x, int y)
    {
        return get(x) == get(y);
    }
    int main()
    {
        cin >> t;
        while (t--)
        {
            scanf("%d%d", &n, &m);
            for (int i = 0; i <= n; i++)//i表示D,i+n表示s
                fa[i] = i,d[i]=0;
            getchar();
            while (m--)
            {
                char op;
                int a, b;
                scanf("%c%d%d", &op, &a, &b);
                getchar();
                if (op == 'D')
                {
                    int p = get(a), q = get(b);
                    fa[p] = q;
                    d[p] = d[a] ^ d[b] ^ 1;
                }
                else
                {
                    if (!same(a, b))
                        printf("Not sure yet.
    ");
                    else if (d[a]^d[b]==1)
                        printf("In different gangs.
    ");
                    else 
                        printf("In the same gang.
    ");
                }
            }
        }
        return 0;
    }
    View Code

     

  • 相关阅读:
    【转】 linux iio子系统
    【转】eclipse -- the project was not built due to a resource exists with a different case...
    Android常用的一些make命令(转载)--不错
    【转】Android Recovery模式
    chain rule 到 Markov chain
    chain rule 到 Markov chain
    贝叶斯统计(Bayesian statistics) vs 频率统计(Frequentist statistics):marginal likelihood(边缘似然)
    贝叶斯统计(Bayesian statistics) vs 频率统计(Frequentist statistics):marginal likelihood(边缘似然)
    企业文化与发展战略
    企业文化与发展战略
  • 原文地址:https://www.cnblogs.com/xiaoguapi/p/10502489.html
Copyright © 2011-2022 走看看