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.\n");
                else if (same(a + n, b))
                    printf("In different gangs.\n");
                else
                    printf("Not sure yet.\n");
            }
        }
    }
    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.\n");
                else if (d[a]^d[b]==1)
                    printf("In different gangs.\n");
                else 
                    printf("In the same gang.\n");
            }
        }
    }
    return 0;
}
View Code

 

猜你喜欢

转载自www.cnblogs.com/xiaoguapi/p/10502489.html