手动博客搬家:本文发表于20170805 21:25:49, 原地址https://blog.csdn.net/suncongbo/article/details/76735893

URL: http://poj.org/problem?id=1703

题目大意:本题即很经典的“龙帮虎帮”问题。
有n个元素(n<=1e5),分布在两个不同的集合里。
现在有M个语句(m<=1e5),每个语句共两种:(1) 给定某两个元素在不同的集合中。(2) 询问两个元素是否在同一集合中。对于是、否、无法确定的情况,分别输出"In the same gang.", "In different gangs.", "Not sure yet."
思路分析:假如给定的是两个元素在同一集合中,思路就很明确了。
但是现在给定的是两个元素不同集合,而且已知仅有两个集合,于是我们就可以想办法将其转化为两元素同集合问题。
设有元素A,B, 则我们将每个元素分别“克隆”为A', B', 但将她们放入分别与本身不同的另外一个集合中。
同时,保证A和A', B和B', ..., 永远不会同集合。
然后,假如已知A与B不同集合,则需将A和B', B和A'分别放入同一集合(union操作),假如已知A与B同集合,则需把A和B, A'和B'进行union一下即可。
最后,回答询问时,有以下三种情况:

(1) A与B同集合,或A'与B‘同集合:In the same gang.

(2) A与B'同集合,或B与A'同集合:In different gangs.

(3) 其他:Not sure yet.
代码呈现:(Time:532MS ,Memory:960K ,Code:1005B)

#include<cstdio>
using namespace std;

const int MAXN = 1e5;
int fa[MAXN*2+2];
int n,m;

int find_fa(int u)
{
    int i,j,k;
    
    i = u;
    while(fa[i] != i)
    {
        i = fa[i];
    }
    fa[u] = i;
    j = u;
    while(j != i)
    {
        k = fa[j];
        fa[j] = i;
        j = k;
    }
    return i;
}

int main()
{
    int i,t,p,q,pp,qq,x,y;
    char ch[3];
    
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1; i<=2*n; i++) //Union-Find Sets init
        {
            fa[i] = i;
        }
        for(i=1; i<=m; i++) //calculate while reading
        {
            scanf("%s%d%d",ch,&x,&y);
            if(ch[0] == 'A')
            {
                p = find_fa(x);
                q = find_fa(y);
                pp = find_fa(x+n);
                qq = find_fa(y+n);
                if(p == q) printf("In the same gang.\n");
                else if(pp == q || p == qq) printf("In different gangs.\n");
                else printf("Not sure yet.\n");
            }
            else if(ch[0] == 'D')
            {
                p = find_fa(x);
                q = find_fa(y);
                pp = find_fa(x+n);
                qq = find_fa(y+n);
                if(pp != q) fa[pp] = q;
                if(qq != p) fa[qq] = p;
            }
        }
    }
    
    return 0;
}

类似题目:poj 2492 A Bug's Life (几乎一模一样)
poj 1182 && luogu P2024 [NOI 2001]食物链 (一样的思路,元素分成三类)
luogu P1525 [NOIP 2010提高组] 关押罪犯 (个人认为难度较大)