题目链接

题意

有一种\(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 二分图染色 || 种类并查集的更多相关文章

  1. NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...

  2. POJ 2492 A Bug's Life(带权并查集)

    题目链接:http://poj.org/problem?id=2492 题目大意:有n只虫子,m对关系,m行每行有x y两个编号的虫子,告诉你每对x和y都为异性,先说的是对的,如果后面给出关系与前面的 ...

  3. poj 2492 a bug's life 简单带权并查集

    题意大致为找同性恋的虫子.... 这个比食物链要简单些.思路完全一致,利用取余操作实现关系之间的递推. 个人感觉利用向量,模和投影可能可以实现具有更加复杂关系的并查集. #include<ios ...

  4. poj 2492 A Bug's Life【带权并查集】

    就是给一个无向图判是否有奇环 用带权并查集来做,边权1表示连接的两个节点异性,否则同性,在%2意义下进行加法运算即可,最后判相同的时候也要%2,因为可能有负数 #include<iostream ...

  5. 【进阶——种类并查集】hdu 1829 A Bug's Life (基础种类并查集)TUD Programming Contest 2005, Darmstadt, Germany

    先说说种类并查集吧. 种类并查集是并查集的一种.但是,种类并查集中的数据是分若干类的.具体属于哪一类,有多少类,都要视具体情况而定.当然属于哪一类,要再开一个数组来储存.所以,种类并查集一般有两个数组 ...

  6. poj2492 A Bug's Life【基础种类并查集】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298148.html   ---by 墨染之樱花 题目链接:http://poj.org/pr ...

  7. hdoj-1289-A Bug&#39;s Life【种类并查集】

    A Bug's Life Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. poj 1182 食物链 &amp;&amp; nyoj 207(种类并查集)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 52414   Accepted: 15346 Description ...

  9. 【POJ - 1703】Find them, Catch them(种类并查集)

    Find them, Catch them 直接翻译了 Descriptions 警方决定捣毁两大犯罪团伙:龙帮和蛇帮,显然一个帮派至少有一人.该城有N个罪犯,编号从1至N(N<=100000. ...

随机推荐

  1. vtigercrm安装

    vtigercrm是一个用户关系管理系统. 本以为安装只用半个小时就可以完成,结果花了两天时间.. 后来因为不想其他的因素影响,重新装了个纯净的系统.(系统为ubuntu16,安装过程略) 在系统基础 ...

  2. 使用python3调用MyQR库生成动态二维码(附源代码)

    可生成普通二维码.带图片的艺术二维码(黑白与彩色).动态二维码(黑白与彩色). GitHub:https://github.com/sylnsfar/qrcode 中文版:https://github ...

  3. LeetCode(164)Maximum Gap

    题目 Given an unsorted array, find the maximum difference between the successive elements in its sorte ...

  4. Windows下新建多级文件夹

    使用system函数调用系统命令"md" 注意:字符串变量的话赋值时要使用双斜杠"\\": system("md C:\\newfolder\\&qu ...

  5. 深入理解Python中的进程

    1.进程的概念什么是进程—>CPU在同一时刻只能处理一个任务,只是因为cpu执行速度很快. cpu在各个任务之间来回的进行切换. 进程的概念:正在进行的一个过程或者说一个任务,而负责执行任务的则 ...

  6. mysql PacketTooBigException 的处理方式

    SHOW VARIABLES LIKE '%max_allowed_packet%'; set global max_allowed_packet = 2*1024*1024*1000

  7. Asp.net HttpWebRequest和HttpWebResponse发送和接受任何类型数据

    发送字符串数据发送数据 string strId = "guest"; "; string postData = "userid=" + strId; ...

  8. STL学习笔记1--vector

    C++STL(Standard Template Library)标准模板库是通用类模板和算法的集合.包含一些标准的数据结构的实现如queues(队列),lists(链表),stacks(栈)等.ST ...

  9. mysql primary partition分区

    尝试把数据库一个表分区 ALTER TABLE user PARTITION BY RANGE(TO_DAYS(`date`)) ( PARTITION p1004 VALUES LESS THAN  ...

  10. 使用sami生成文档

    从composer安装sami $ composer require sami/sami composer自动配置完以后,可以先测试一下是否安装成功.只要不带参数的运行一下sami,就会知道结果. $ ...