点击打开链接

Find them, Catch them
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 50757   Accepted: 15554

Description

The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, the police first needs to identify which gang a criminal belongs to. The present question is, given two criminals; do they belong to a same clan? You must give your judgment based on incomplete information. (Since the gangsters are always acting secretly.)

Assume N (N <= 10^5) criminals are currently in Tadu City, numbered from 1 to N. And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. You will be given M (M <= 10^5) messages in sequence, which are in the following two kinds:

1. D [a] [b]
where [a] and [b] are the numbers of two criminals, and they belong to different gangs.

2. A [a] [b]
where [a] and [b] are the numbers of two criminals. This requires you to decide whether a and b belong to a same gang.

Input

The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. Each test case begins with a line with two integers N and M, followed by M lines each containing one message as described above.

Output

For each message "A [a] [b]" in each case, your program should give the judgment based on the information got before. The answers might be one of "In the same gang.", "In different gangs." and "Not sure yet."

Sample Input

1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4

Sample Output

Not sure yet.
In different gangs.
In the same gang.

Source

POJ Monthly--2004.07.18

题意:

一共有n个元素,这些元素要么属于集合1,要么属于集合2,

有m个操作,A  a   b 为询问,D a   b 表示a,b属于不同的集合

解法一:

利用2*n个元素建立并查集,每个元素x,有两种表示:x和x+n

若a,b属于不同集合,则 a和b+n属于同一个集合,a+n和b属于同一个集合

对于每次询问:

若find(a)=find (b),则a和b属于同一个集合

若find(a+n)==find(b)并且find(a)==find(b+n),则a和b属于不同集合

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5+10;
int p[maxn<<1];
int find(int x)
{if(x==p[x])    return x;return p[x]=find(p[x]);
}
void mix(int x,int y)
{int fx=find(x),fy=find(y);if(fx!=fy)p[fx]=fy;
}int main()
{int n,m,t;cin>>t;while(t--){//memset(vis,0,sizeof(vis));cin>>n>>m;for(int i=1;i<=2*n;i++){p[i]=i;}char op[2];int a,b;for(int i=0;i<m;i++){scanf("%s%d%d",op,&a,&b);if(op[0]=='A'){if (find(a) == find(b))printf("In the same gang.\n");else if (find(a)==find(b+n) && find(a+n)==find(b))printf("In different gangs.\n");elseprintf("Not sure yet.\n");}else{mix(a+n,b);mix(a,b+n);}}}return 0;
}

解法二:

带权并查集

r数组记录每个结点与其父亲结点的关系
r[x]=0,代表x与其父亲是在同一个集合
r[x]=1,代表x与其父亲是在不在同一个集合
初始化r[x]=0,每个元素和自己在同一集合

1.find函数在寻找根节点时不断更新r数组
根据子结点与父亲结点的关系,以及父亲结点与爷爷结点的关系,
可以知道子结点与爷爷结点的关系,具体为

若a和b的关系为rab,b和c的关系为rbc,则a和C的关系为rac=(rab+rbc)%2;

(爷爷,父亲) (父亲,儿子) (爷爷,儿子)
0 0 0
0 1 1
1 0 1
1 1 0

2.union函数更新两棵树的关系:
定义:fx 为 x的根节点, fy 为 y 的根节点,联合时,使得fa[ fy ] = fx;
同时也要寻找 fx 和 fy 的关系,其关系为(r[ x ]  + 1 - r[ y ]) % 2;

因为确定了 x 和 y 的关系是 1 ,因此 r[ fy ] = (r[ x ] + 1 - r[ y ]) % 2;


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100005;
int fa[maxn],r[maxn];int find(int x)
{if (fa[x] == x) return fa[x];int tmp = fa[x];fa[x] = find(fa[x]);r[x] = (r[tmp] + r[x]) % 2;return fa[x];
}void unite(int x,int y)
{int fx = find(x),fy = find(y);if (fx == fy)   return;fa[fy] = fx;r[fy] = (r[x] + 1 - r[y]) % 2;
}int main()
{int T;scanf("%d",&T);while (T--){int N,M,x,y;char opt[5];scanf("%d%d",&N,&M);for (int i = 0;i <= N;i++)   fa[i] = i,r[i] = 0;while (M--){scanf("%s %d %d",opt,&x,&y);if (opt[0] == 'A'){if (find(x) == find(y)){if (r[x] == r[y])   printf("In the same gang.\n");else    printf("In different gangs.\n");}else    printf("Not sure yet.\n");}else    unite(x,y);}}return 0;
}

POJ1703 Find them, Catch them 并查集相关推荐

  1. POJ 1703 Find them, Catch them(并查集高级应用)

    POJ 1703 Find them, Catch them(并查集高级应用) 手动博客搬家:本文发表于20170805 21:25:49, 原地址https://blog.csdn.net/sunc ...

  2. POJ 1703 Find them, Catch them 并查集

    题意:给你t组数据,每组数据给你编号为1-n的坏人,这些坏人要么属于团伙A,要么属于团伙B,然后给你m次操作: A操作:询问x和y是不是同一个团伙 D操作:告诉你x和y不是同一个团伙 思路:和POJ ...

  3. POJ1703【Find them, Catch them】(并查集模板题)

    题目地址:POJ1703[Find them, Catch them] 题目描述: Tadu市的警察局决定结束混乱,因此要采取行动,根除城市中的两大帮派:龙帮和蛇帮.然而,警方首先需要确定某个罪犯是属 ...

  4. 【POJ - 1703】Find them, Catch them(带权并查集之--种类并查集 权为与父节点关系)

    题干: Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36176   Accep ...

  5. POJ 1703 Find them, Catch them(路径压缩并查集)

    POJ 1703 Find them, Catch them(路径压缩并查集) 2014年03月11日 20:13:54 阅读数:881 POJ 1703 Find them, Catch them( ...

  6. openoj的一个小比赛(J题解题报告)poj1703(并查集)

    http://openoj.awaysoft.com:8080/judge/contest/view.action?cid=47#problem/J http://poj.org/problem?id ...

  7. POJ1703带权并查集(距离或者异或)

    题意:       有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作 1 D a b 给出a b 两个人不属于同一个帮派 2 A a b 问a b 两个人关系 输出 同一个帮派 ...

  8. Find them, Catch them POJ - 1703(种类并查集)

    题意: 在这个城市里有两个黑帮团伙,现在给出N个人,问任意两个人他们是否在同一个团伙 1.输入D x y代表x于y不在一个团伙里 2.输入A x y要输出x与y是否在同一团伙或者不确定他们在同一个团伙 ...

  9. POJ 1703 Find them, Catch them 种类并查集

    题意 给出一堆点和关系 D为两点不同集合 A为查询两点是否不同集合 n<=1e5 code #include<cstdio> #include<iostream> #in ...

最新文章

  1. ERP实施中要重视物料编码的规则
  2. 前端js自动填写 点击_爬虫自动填写学生健康打卡表
  3. java怎么表示正无穷大_有什么比无穷大更大,比无穷小更小?
  4. 7-6 区间覆盖 (10 分)(思路+详解)Come 宝!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  5. C++安全方向(三):3.2 单项散列函数的应用场景
  6. string会被回收吗_互联网大厂面试题:这些面试都会吗?就想要30k?
  7. Nginx安装问题记录
  8. 10 分钟看懂消息队列 RocketMQ
  9. Spring Boot 中实现定时任务的常用方式@Scheduled
  10. NI控制原型平台配置(硬件+软件)
  11. android 框架作用是什么意思,Android系统上的Xp框架有什么用
  12. 怎么样选择合适的CFA备考资料
  13. Python: 常用的软件包
  14. C语言中写保护的作用,C语言考试试题练习
  15. Linux下键盘测试工具
  16. ready与onload的区别
  17. java 定时器 每天凌晨_java定时器 每天凌晨 固定执行一个方法
  18. 数据库设计中的英文术语表
  19. 最佳 Maya 免费建模插件!
  20. android 保存图片到手机相册,并通知相册刷新

热门文章

  1. [Hive]-函数篇
  2. linux安装软件的几种方式(kali平台)和一些实用的软件(持续更新)
  3. 顺序表基本操作函数总结
  4. 20145104张家明实验五
  5. [z]IE6各种不兼容问题
  6. SimpleMembership
  7. 在Netbeans下配置Tomcat manager用户名与密码
  8. Linux 进程内 全局看见,Android获得全局进程信息以及进程使用的内存情况
  9. java库net2.0下载_.NET Framework各版本独立下载.NET Framework 3.5下载.NET Framework 2.0下载...
  10. python创建软连接_centos7 上 创建软连接 ln -s