POJ 1703 Find them, Catch them【并查集】

题意: 有 N 个人分属于两个帮派,对应两种操作:

          A   X Y      询问x,y 是否属于一个帮派,或两者关系不能确定。

          D   X Y      X和Y 分属不同帮派

分析: 感觉就是简化版的食物链...

方法一:

           加一个数组 r[i]

           r[i] = 0  表示 i 与祖先属于同一个帮派

           r[i] = 1  表示 i 与祖先属于不同帮派

View Code
#include<stdio.h>
#include<string.h>
int f[100005];
int r[100005];
int find(int x)
{
    int s;
    if(f[x]==-1)
        return x;
    else s=find(f[x]);
    r[x]=(r[x]+r[f[x]])%2;
    f[x]=s;
    return s;
}
void join(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
    {
        f[fy]=fx;
        r[fy]=(r[x]+r[y]+1)%2;
    }
}
int main()
{
    char c[2];
    int t,i,a,b,n,m,fx,fy;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++){
            f[i]=-1;
            r[i]=0;
        }
    //    scanf("%c",&c);
        while(m--)
        {
            scanf("%s%d%d",c,&a,&b);
            if(c[0]=='A')
            {
                fx=find(a);
                fy=find(b);
                if(fx==fy)
                {
                    if(r[a]==r[b])
                         printf("In the same gang.\n");
                    else printf("In different gangs.\n");
                }
                else printf("Not sure yet.\n");
            }
            else join(a,b);
        //    scanf("%c",&c);
        }
    }
    return 0;
}


方法二:

             对于每一个人 i    ,都假设 i + n  和他对立,假如 j 和 i+n 对立,那么 j 和 i 必属与于同一个派别,若 j 和 i+n属于同一个集合,那么i 和 j 一定对立。

      

View Code
#include<stdio.h>
#include<string.h>
int f[200005];
int find(int x)
{
    return f[x]==x?x:(f[x]=find(f[x]));
}
void join(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
        f[fy]=fx;
}
int main()
{
    char s[2];
    int t,n,m,a,b,fx,fy,i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=2*n;i++)
            f[i]=i;
        while(m--)
        {
            scanf("%s%d%d",s,&a,&b);
            if(s[0]=='A')
            {
                if(find(a+n)==find(b))
                    printf("In different gangs.\n");
                else if(find(a)==find(b))
                    printf("In the same gang.\n");
                else printf("Not sure yet.\n");
            }
            else
            {
                join(a,b+n);
                join(b,a+n);
            }
        }
    }
    return 0;
}

 

posted @ 2012-08-07 15:40  'wind  阅读(189)  评论(0编辑  收藏  举报