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;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2594118.html