POJ 1703 Find them, Catch them(并查集)

Description
在这个城市里有两个黑帮团伙,现在给出n个人,每个人都属于这两个帮派中的一个,m次操作,操作分两种:
1.D x y:x于y不在一个团伙里
2.A x y:查询x与y的关系,即是否在同一团伙或者不确定
Input
第一行一个整数T表示用例组数,每组用例第一行为两个整数n和m分别表示人数和操作数,之后m行每行表示一种操作(1<=n<=100000)
Output
对于每次查询,如果两个人在一个团伙则输出”In the same gang.“,如果两个人不在一个团伙则输出”In different gangs.“,如果不确定则输出”Not sure yet.“
Sample Input
1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4
Sample Output
Not sure yet.
In different gangs.
In the same gang.
Solution
并查集,食物链弱化版,对每个人i建立两个元素i和i+n分别表示这个人属于团伙1和团伙2,则
1.两个人不属于同一团伙:unite(x,y+n),unite(x+n,y)
2.判断两人是否属于同一团伙:same(x,y)表示x和y属于同一团伙,same(x,y+n)表示x和y属于不同团伙,两者都不成立说明x和y关系不确定
Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 211111 
int par[maxn];
int deep[maxn]; 
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        par[i]=i;
        deep[i]=0;
    }
} 
int find(int x) 
{
    if(par[x]==x) return x;
    else return par[x]=find(par[x]);
}
void unite(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y) return;
    if(deep[x]<deep[y]) par[x]=y;
    else
    { 
        par[y]=x;
        if(deep[x]==deep[y]) deep[x]++;
    } 
}
bool same(int x,int y)
{
    return find(x)==find(y);
}
int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        char op[3];
        int x,y;
        init(2*n);
        while(m--)
        {
            scanf("%s%d%d",op,&x,&y);
            if(op[0]=='A')
            {
                if(same(x,y))printf("In the same gang.\n");
                else if(same(x,y+n))printf("In different gangs.\n");
                else printf("Not sure yet.\n");
            }
            else unite(x,y+n),unite(x+n,y);
        }
    }
    return 0;
}

你可能感兴趣的:(POJ 1703 Find them, Catch them(并查集))