POJ 1703 Find them, Catch them

题意

塔都市的警察局决定治理混乱,从城市中的两个帮派开始行动,Gang Dragon和Gang Snake。但是,警方首先需要确定犯罪分子属于哪个团伙。目前的问题是,两名罪犯,他们属于同一个帮派吗?您必须根据不完整的信息做出判断。(因为歹徒总是暗中行动。)

假设\(N(N<= 10^5)\)罪犯目前在塔都市,编号从1到N。当然,他们中至少有一人属于Gang Dragon,同样至少有一人属于Gang Snake。将按顺序给出\(M(M<= 10^5)\)个消息,它们分为以下两种:

  1. D [a][b]
    其中[a]和[b]是两个罪犯的编号,以及他们属于不同的帮派。
  2. A [a] [b]
    其中[a]和[b]是两个罪犯的编号。这需要您回答a和b是否属于同一个帮派。

对于每种情况下的每条消息“A [a][b]”,您的程序应根据之前获得的信息进行判断。答案可能是“在同一帮派中”,“在不同的帮派中”和“还不确定”。

思路

不同集合查询方法:

  • (Find(y+n) == Find(x) || Find(x+n) == Find(y)) 不同集合
  • (Find(x) == Find(y) || Find(x+n) == Find(y+n)) 相同集合
  • 不确定是否同一集合
const int N=1e5+10;
int p[N<<1];
int n,m;

int find(int x)
{
    if(x != p[x]) p[x]=find(p[x]);
    return p[x];
}

void merge(int a,int b)
{
    int pa=find(a);
    int pb=find(b);
    if(pa != pb) p[pa]=pb;
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>m;

        for(int i=1;i<=n*2;i++) p[i]=i;

        while(m--)
        {
            char op[2];
            int a,b;
            scanf("%s%d%d",op,&a,&b);
            if(op[0] == 'D')
            {
                merge(a,b+n);
                merge(a+n,b);
            }
            else
            {
                if(find(a) == find(b))
                    puts("In the same gang.");
                else if(find(a) == find(b+n))
                    puts("In different gangs.");
                else
                    puts("Not sure yet.");
            }
        }
    }
    //system("pause");
    return 0;
}
posted @ 2021-03-04 22:03  Dazzling!  阅读(48)  评论(0编辑  收藏  举报