poj 1703 Find them,Catch them

说一下题意:

某市公安局决定要将该市的两个犯罪团伙连根拔起,一个是神龙帮,另外一个是灵蛇帮。目前的问题是,给你两个罪犯,判断他们各自属于哪一个帮派,你只能根据你已经

知道的不完整的信息来判定。

假设该市有N个罪犯,编号是1到N,当然,他们中不是神龙帮的就是灵蛇帮的,你将得到关于他们的M条信息。

(1)D a b 

   a, b是两个罪犯的编号,并且他们属于不同的帮派

(2)A a b

  a, b 是两个罪犯的编号,这条信息是向你询问 这两个罪犯是否属于同一个帮派。

处理问题的关键就是 处理好并查操作时,节点之间的关系的建立和更新。

Step 1: 解题前首先要确定用某种方式来表示节点与根节点的关系,例如可以用  0 ,1分别标记某一个节点与树根的同异帮关系。据此可以写好并查集的查找函数

Step 2: 可以先认为每个节点都是树根且都与自身同帮派,据此初始化标记变量。

Step 3:对每组输入数据进行处理,若两个节点的根节点不同,若A操作,则无法确认两者的关系,若D操作,则合并两个节点所在树且更新节点关系;

若两个节点的根节点相同,则根据这两个节点与根节点的关系来判定这两个节点的关系,并给出相应的输出。

附上代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#define N 1000100
using namespace std;
int f[N],c[N],key;
int find(int x)
{
 if(f[x]==x)return x;
 int t=f[x];
     f[x]=find(f[x]);
     c[x]=(c[x]+c[t])%2;
    return f[x];
}
void make(int a,int b)
{
  int f1=find(a);
  int f2=find(b);
  if(f1!=f2)
  {
    f[f1]=f2;
    if((c[a]+c[b])%2==0)
         c[f1]=1;
  }
  else
  {
    if((c[a]+c[b])%2==0)
     key=1;
    else
     key=2;
  }
}
int main()
{
 int n,m,t;
 scanf("%d",&t);
 while(t--)
 {
  scanf("%d%d",&n,&m);
  memset(c,0,sizeof(c));
  for(int i=1;i<=n;i++)
      f[i]=i;
  char s[10];
  int a,b; 
  for(int i=0;i<m;i++)
  {
     scanf("%s%d%d",s,&a,&b);
     key=0;
    if(s[0]=='A')
    {
        int fa=find(a);
        int fb=find(b);
        if(fa!=fb)
          printf("Not sure yet.\n");
        else
         {
           make(a,b);
          if(key==2)
             printf("In different gangs.\n");
          else if(key==1)
             printf("In the same gang.\n"); 
         }
    }
    else if(s[0]=='D')
    {
       make(a,b); 
    }
  }
    
 }
 return 0;   
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值