poj 2492 A Bug's Life 二分图染色 || 种类并查集
题目链接
题意
有一种\(bug\),所有的交往只在异性间发生。现给出所有的交往列表,问是否有可疑的\(bug\)(进行同性交往)。
思路
法一:种类并查集
参考:https://www.2cto.com/kf/201310/249052.html
对于每一个集合中的元素,用一个数组\(rank\)记录它和它的祖先性别是否相同,\(0\)为相同,\(1\)为不同。每个祖先的\(rank\)值为\(0\).
路径压缩时:rank[x] = rank[prev_fa]^rank[x];
因为是递归进行的路径压缩,所以更新\(x\)的\(rank\)时,它之前父亲的\(rank\)值已经被更新过了,因为\(0\)表示相同,\(1\)表示不同,所以若\(rank[x]=0\),意味着\(x\)和它之前父亲的性别一样,其和新父亲的关系 和 原父亲与新父亲的关系 相同;若\(rank[x]=1\),意味着\(x\)和它之前父亲的性别不同,其和新父亲的关系 和 原父亲与新父亲的关系 不同。其实就是异或。
合并时:rank[xx]=!(rank[x]^rank[y]);
这里\(x\)的父亲为\(xx\),\(y\)的父亲为\(yy\). 若\(rank[x]==rank[y]\),因为\(x\)和\(y\)性别不同,而\(x\)和\(xx\)性别的关系与\(y\)和\(yy\)性别的关系相同,所以\(xx\)和\(yy\)性别不同;若\(rank[x]!=rank[y]\),因为\(x\)和\(y\)性别不同,而\(x\)和\(xx\)性别的关系与\(y\)和\(yy\)性别的关系也不同,所以\(xx\)和\(yy\)性别相同。其实就是同或。
法二:判断二分图
也可以用并查集写~
Code
Ver. 1
#include <stdio.h>
#include <iostream>
#define maxn 2010
using namespace std;
typedef long long LL;
int fa[maxn], rk[maxn], sz[maxn];
int find(int x) {
if (fa[x] == x) return x;
int tmp = fa[x];
fa[x] = find(fa[x]);
rk[x] = rk[tmp] ^ rk[x];
return fa[x];
}
int kas;
void work() {
printf("Scenario #%d:\n", ++kas);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) sz[i] = 1, fa[i] = i, rk[i] = 0;
bool flag = false;
for (int i = 0; i < m; ++i) {
int x, y;
scanf("%d%d", &x, &y);
if (flag) continue;
int xx = find(x), yy = find(y);
if (xx == yy) {
if (rk[x] == rk[y]) flag = true;
}
else {
if (sz[xx] > sz[yy]) swap(xx, yy), swap(x, y);
fa[xx] = yy; rk[xx] = !(rk[x] ^ rk[y]); sz[yy] += sz[xx];
}
}
if (flag) printf("Suspicious bugs found!\n\n");
else printf("No suspicious bugs found!\n\n");
}
int main() {
int T;
scanf("%d", &T);
while (T--) work();
return 0;
}
Ver.2
#include <stdio.h>
#include <iostream>
#define maxn 4010
using namespace std;
typedef long long LL;
int fa[maxn], rk[maxn], sz[maxn];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void unionn(int x, int y) {
x = find(x), y = find(y);
if (sz[x] > sz[y]) swap(x, y);
fa[x] = y, sz[y] += sz[x];
}
int kas;
void work() {
printf("Scenario #%d:\n", ++kas);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= 2*n; ++i) sz[i] = 1, fa[i] = i;
for (int i = 0; i < m; ++i) {
int x, y;
scanf("%d%d", &x, &y);
unionn(x, y+n), unionn(y, x+n);
}
bool flag = false;
for (int i = 1; i <= n; ++i) if (find(i)==find(i+n)) { flag = true; break; }
if (flag) printf("Suspicious bugs found!\n\n");
else printf("No suspicious bugs found!\n\n");
}
int main() {
int T;
scanf("%d", &T);
while (T--) work();
return 0;
}
poj 2492 A Bug's Life 二分图染色 || 种类并查集的更多相关文章
- NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
- POJ 2492 A Bug's Life(带权并查集)
题目链接:http://poj.org/problem?id=2492 题目大意:有n只虫子,m对关系,m行每行有x y两个编号的虫子,告诉你每对x和y都为异性,先说的是对的,如果后面给出关系与前面的 ...
- poj 2492 a bug's life 简单带权并查集
题意大致为找同性恋的虫子.... 这个比食物链要简单些.思路完全一致,利用取余操作实现关系之间的递推. 个人感觉利用向量,模和投影可能可以实现具有更加复杂关系的并查集. #include<ios ...
- poj 2492 A Bug's Life【带权并查集】
就是给一个无向图判是否有奇环 用带权并查集来做,边权1表示连接的两个节点异性,否则同性,在%2意义下进行加法运算即可,最后判相同的时候也要%2,因为可能有负数 #include<iostream ...
- 【进阶——种类并查集】hdu 1829 A Bug's Life (基础种类并查集)TUD Programming Contest 2005, Darmstadt, Germany
先说说种类并查集吧. 种类并查集是并查集的一种.但是,种类并查集中的数据是分若干类的.具体属于哪一类,有多少类,都要视具体情况而定.当然属于哪一类,要再开一个数组来储存.所以,种类并查集一般有两个数组 ...
- poj2492 A Bug's Life【基础种类并查集】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298148.html ---by 墨染之樱花 题目链接:http://poj.org/pr ...
- hdoj-1289-A Bug's Life【种类并查集】
A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- poj 1182 食物链 && nyoj 207(种类并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 52414 Accepted: 15346 Description ...
- 【POJ - 1703】Find them, Catch them(种类并查集)
Find them, Catch them 直接翻译了 Descriptions 警方决定捣毁两大犯罪团伙:龙帮和蛇帮,显然一个帮派至少有一人.该城有N个罪犯,编号从1至N(N<=100000. ...
随机推荐
- 01_9_ServletContext
01_9_ServletContext 1. 例子 public void doGet(HttpServletRequest request, HttpServletResponse response ...
- 数组char a[4] 保存了一个数据,怎么转换为unsigned int呢 ?
[待解决问题] 浏览: 701次 注意char并不表示字符的 a[0]=0; a[1]=0; a[2]=3; a[3]=0; 那么我要的unsigned int b应该等于: b= 0x0000030 ...
- Where do I belong-freecodecamp算法题目
Where do I belong(数组排序并找出元素索引) 要求 给数组排序 找到指定的值在数组的位置,并返回位置对应的索引. 思路 设定.sort()需要的返回函数 将要搜索的值添加到数组内 用. ...
- Java中的==和equals的区别详解
1.基础知识 (1)String x = "hello"; (2)String x = new String ("hello"); 第1种方式的工作机制是,首先 ...
- 收集的免费API接口
1.IP地址调用接口 这是淘宝的IP调用API http://ip.taobao.com/service/getIpInfo.php?ip=$ip 返回值:{"code":0,&q ...
- Ubuntu下安装anaconda和pycharm
折腾了一上午,终于装好了,如下:Python环境的安装: 安装anaconda 建议去https://www.anaconda.com/download/#linux直接用Ubuntu界面的搜狐浏览器 ...
- Python全栈开发第二期课表
day01-python 全栈开发-基础篇 01 开课介绍 01:55:13 ★ 02 开课介绍02 01:28:31 ★ 03 开课介绍03 00:22:55 ...
- 0016.Linux基础之常用基本命令讲解
开启linux系统,开启xshell pwd:printing workding directory 打印当前目录 /:代表根目录 cd:change directory 改变目录 ls:list 查 ...
- 命令行客户端操作pg数据库常用操作
登录 # su - postgres -c "psql" 或者 $psql -U user_name -d database_name -h serverhost psql (10 ...
- Django底层原理简介与安装
Django环境目录搭建一栏: 利用wsgiref模块封装好的socket搭建服务端: #利用wsgiref模块封装好的socket演示操作(例如accept\recv) #也可以实现socket服务 ...