POJ1703 Find them, Catch them 并查集
点击打开链接
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 50757 | Accepted: 15554 |
Description
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
Output
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
题意:
一共有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 并查集相关推荐
- POJ 1703 Find them, Catch them(并查集高级应用)
POJ 1703 Find them, Catch them(并查集高级应用) 手动博客搬家:本文发表于20170805 21:25:49, 原地址https://blog.csdn.net/sunc ...
- POJ 1703 Find them, Catch them 并查集
题意:给你t组数据,每组数据给你编号为1-n的坏人,这些坏人要么属于团伙A,要么属于团伙B,然后给你m次操作: A操作:询问x和y是不是同一个团伙 D操作:告诉你x和y不是同一个团伙 思路:和POJ ...
- POJ1703【Find them, Catch them】(并查集模板题)
题目地址:POJ1703[Find them, Catch them] 题目描述: Tadu市的警察局决定结束混乱,因此要采取行动,根除城市中的两大帮派:龙帮和蛇帮.然而,警方首先需要确定某个罪犯是属 ...
- 【POJ - 1703】Find them, Catch them(带权并查集之--种类并查集 权为与父节点关系)
题干: Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 36176 Accep ...
- 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( ...
- openoj的一个小比赛(J题解题报告)poj1703(并查集)
http://openoj.awaysoft.com:8080/judge/contest/view.action?cid=47#problem/J http://poj.org/problem?id ...
- POJ1703带权并查集(距离或者异或)
题意: 有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作 1 D a b 给出a b 两个人不属于同一个帮派 2 A a b 问a b 两个人关系 输出 同一个帮派 ...
- Find them, Catch them POJ - 1703(种类并查集)
题意: 在这个城市里有两个黑帮团伙,现在给出N个人,问任意两个人他们是否在同一个团伙 1.输入D x y代表x于y不在一个团伙里 2.输入A x y要输出x与y是否在同一团伙或者不确定他们在同一个团伙 ...
- POJ 1703 Find them, Catch them 种类并查集
题意 给出一堆点和关系 D为两点不同集合 A为查询两点是否不同集合 n<=1e5 code #include<cstdio> #include<iostream> #in ...
最新文章
- ERP实施中要重视物料编码的规则
- 前端js自动填写 点击_爬虫自动填写学生健康打卡表
- java怎么表示正无穷大_有什么比无穷大更大,比无穷小更小?
- 7-6 区间覆盖 (10 分)(思路+详解)Come 宝!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- C++安全方向(三):3.2 单项散列函数的应用场景
- string会被回收吗_互联网大厂面试题:这些面试都会吗?就想要30k?
- Nginx安装问题记录
- 10 分钟看懂消息队列 RocketMQ
- Spring Boot 中实现定时任务的常用方式@Scheduled
- NI控制原型平台配置(硬件+软件)
- android 框架作用是什么意思,Android系统上的Xp框架有什么用
- 怎么样选择合适的CFA备考资料
- Python: 常用的软件包
- C语言中写保护的作用,C语言考试试题练习
- Linux下键盘测试工具
- ready与onload的区别
- java 定时器 每天凌晨_java定时器 每天凌晨 固定执行一个方法
- 数据库设计中的英文术语表
- 最佳 Maya 免费建模插件!
- android 保存图片到手机相册,并通知相册刷新
热门文章
- [Hive]-函数篇
- linux安装软件的几种方式(kali平台)和一些实用的软件(持续更新)
- 顺序表基本操作函数总结
- 20145104张家明实验五
- [z]IE6各种不兼容问题
- SimpleMembership
- 在Netbeans下配置Tomcat manager用户名与密码
- Linux 进程内 全局看见,Android获得全局进程信息以及进程使用的内存情况
- java库net2.0下载_.NET Framework各版本独立下载.NET Framework 3.5下载.NET Framework 2.0下载...
- python创建软连接_centos7 上 创建软连接 ln -s