您的位置:首页 > 其它

刷题——Find them, Catch them POJ - 1703

2017-08-23 19:03 405 查看
/*

有n个人这n个人来自与两个帮派,现在有两种操作

D a b,a b不属于一个帮派

A a b,a b的关系,是同一个帮派,还是不同的,还是不确定

用一个数组来确定是否有联系rt[],再用一个数组来存放有联系人处于那个帮派gan[]

他们之间的联系,就跟平常所用的并查集一样,最主要的是在有联系的人上

先将所处的帮派全部设为1,(01两个帮派)

这样子每一个关系带的头都是1

假设a b处在不同帮派

将a的头连入b的头,那么gan[a]=(gan[a]+gan[b])%2

若a,b的gan相同,那么a原先所处的帮派全部变换0->1,1->0

若a,b的gan不同那么a和b原先所属的gan不用变换

变换的过程若头两个为1,1就是说gan不用更新

连续的gan会出现两种种情况:1,1(现头,原头);1,0(原头,原子)

gan[x]=(gan[x](子节点)+gan[temp](父节点)+1)%2 (1+1+1)%2=1;(0+1+1)%2=0;

变换的过程若头两个为1,0就是说gan要更新

连续的gan会出现两种种情况:1,0(现头,原头);0,0(原头,原子)

gan[x]=(gan[x]+gan[temp]+1)%2 (1+1+1)%2=1;(0+0+1)%2=0;

更新的过程子都连接到头了

*/

#include <stdio.h>

int rt[100010];

int gan[100010];

int find(int x)

{

    if(rt[x]==x){

4000

        return rt[x];

    }

    int temp=rt[x];

    rt[x]=find(rt[x]);

    gan[x]=(gan[x]+gan[temp]+1)%2;

    return rt[x];

}

void un(int x,int y){

    int a=find(x);

    int b=find(y);

    if(a!=b){

        rt[a]=b;

        gan[a]=(gan[x]+gan[y])%2;

    }

}

int main(){

    int t,n,m,a,b;

    char op[2];

    scanf("%d",&t);

    while(t--){

        scanf("%d %d",&n,&m);

        for(int i=1;i<=n;i++){

            rt[i]=i;

            gan[i]=1;

        }

        for(int i=0;i<m;i++){

            scanf("%s %d %d",op,&a,&b);

            if(op[0]=='D'){

                un(a,b);

            }

            else{

                if(find(a)!=find(b)){

                    printf("Not sure yet.\n");

                }

                else{

                    if(gan[a]==gan[b]){

                        printf("In the same gang.\n");

                    }

                    else{

                        printf("In different gangs.\n");

                    }

                }

            }

        }

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: