poj 1703 Find them,Catch them

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

题目大意:

有一些罪犯,分两伙 每伙至少一个

两种操作

D a b:a和b不是一伙的

A a b:a和b 之间的关系是什么

思路:

并查集,先把可以确定关系的罪犯放在一个集里 再多一个数组

表示此节点和他指向的上一个节点是否一样(是否同伙)

代码及其注释:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<cmath>

#include<queue>

#include<algorithm>

#include<set>



using namespace std;



const int N=100010;



int f[N];//他指向的上一个节点

int same[N];//和他指向的上一个节点是否同伙 1表示同伙 0表示不同伙

int findf(int x)

{

    if(f[x]!=x)

    {

        int temp=f[x];//暂存

        f[x]=findf(f[x]);

        if(same[x]==same[temp])//更新所指向节点后 关系也要更新

        {

            same[x]=1;

        }else

        {

            same[x]=0;

        }

    }

    return f[x];

}

int main()

{

   int T;

   scanf("%d",&T);

   while(T--)

   {

       int n,m;

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

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

       {

           f[i]=i;

           same[i]=1;

       }

       while(m--)

       {

           char c;

           int x,y;

           getchar();

           scanf("%c %d %d",&c,&x,&y);

           if(c=='D')

           {

                int xf=findf(x);

                int yf=findf(y);

                f[xf]=yf;

                if(same[x]==same[y])

                {

                    same[xf]=0;

                }else

                {

                    same[xf]=1;

                }

           }else

           {

               if(n==2)//注意只有2个人的情况

               {

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

                   continue;

               }

               if(findf(x)!=findf(y))//是否可以确定关系 而且经过findf()函数 此点已经指向根节点

               {

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

               }else if(same[x]==same[y])//和根节点的关系是否一样

               {

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

               }else

               {

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

               }

           }



       }





   }

   return 0;

}

  

你可能感兴趣的:(catch)