题目链接

http://poj.org/problem?id=2492

题意

虫子有两种性别,有n只虫子,编号1~n,输入m组数据,每组数据包含a、b两只虫子,表示a、b为不同性别的虫子,根据输入的m组数据是否出现前后矛盾(如a、b在前面判断为同性,而后又得出a、b为异性)进行相应的输出。

思路

使用并查集求解,但该题比普通并查集题目复杂了一些,该题需要使用树中结点的权值来记录信息,在代码中使用数组r[]来记录某结点和其父结点之间的性别是否相同,若r[x]=0,则说明虫子x和其父结点同性,若r[x]=1,则说明x与其父结点异性,这也是“带权”的含义。

代码

 #include <cstdio>

 const int N =  + ;
int p[N];
int r[N]; void make_set(int n)
{
for (int i = ;i <= n;i++)
{
p[i] = -;
r[i] = ;
}
} int find_root(int x)
{
if (p[x] == -) return x; int t = p[x];
p[x] = find_root(p[x]);
r[x] = (r[x] + r[t]) % ;
return p[x];
} void union_set(int a, int b)
{
int ra = find_root(a);
int rb = find_root(b); p[ra] = rb;
r[ra] = (r[a] + r[b] + ) % ;
} int main()
{
//freopen("poj2492.txt", "r", stdin);
int t;
scanf("%d", &t);
int cnt = ;
while (t--)
{
int n, m;
scanf("%d%d", &n, &m);
make_set(n);
bool flag = true;
int a, b;
for (int i = ; i < m; i++)
{
scanf("%d%d", &a, &b);
if (find_root(a) == find_root(b))
{
if (r[a] == r[b])
{
flag = false;
continue;
}
}
else union_set(a, b);
}
printf("Scenario #%d:\n", ++cnt);
if (flag)
puts("No suspicious bugs found!\n");
else puts("Suspicious bugs found!\n");
}
return ;
}

分析

第一次做带权并查集,下面是我对代码的一些分析:

1、首先要注意函数int find_root(int x)。函数find_root不仅进行了路径压缩,而且还更新了结点和其父结点之间的关系,更新后的关系r[x]=(r[x]+r[t])%2,其中t为x的父结点。为什么是r[x]=(r[x]+r[t])%2呢?首先要知道路径压缩后树变成了2层,每个结点直接与根结点相连,假设有3只虫子a、b、c,关系如下

则更新前有r[a]=1,r[b]=1,更新后r[a]=0=(r[a]+r[b])%2,考虑全部情况,则可以得到下表:

更新前r[a] r[b] 更新后r[a]
0 0 0
0 1 1
1 0 1
1 1 0

可以看到有r[a]=(r[a]+r[b])%2(其实就是把更新前r[a]和r[b]做了一次异或操作得到新的r[a],写成r[a]=r[a]^r[b]也可以)。

2、还要注意函数union_set中为什么会有r[ra]=(r[a]+r[b]+1)%2?分析方法和上面是相同的,把r[a]、r[b]、r[ra]的值列举出来就可以发现r[ra]=(r[a]+r[b]+1)%2

相似题目

1、poj1703

poj2492 A Bug's Life(带权并查集)的更多相关文章

  1. POJ2492 A Bug's Life 带权并查集

    分析:所谓带权并查集,就是比朴素的并查集多了一个数组,记录一些东西,例如到根的距离,或者和根的关系等 这个题,权数组为relation 代表的关系  1 和父节点不同性别,0,和父节点同性别 并查集一 ...

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

    题意: 思路: mod2 意义下的带权并查集 如果两只虫子是异性恋,它们的距离应该是1. 如果两只虫子相恋且距离为零,则它们是同性恋. (出题人好猥琐啊) 注意: 不能输入一半就break出来.... ...

  3. poj2492A Bug's Life——带权并查集

    题目:http://poj.org/problem?id=2492 所有元素加入同一个并查集中,通过其偏移量%2将其分类为同性与异性,据此判断事件. 代码如下: #include<iostrea ...

  4. POJ 2492 A Bug's Life (带权并查集 && 向量偏移)

    题意 : 给你 n 只虫且性别只有公母, 接下来给出 m 个关系, 这 m 个关系中都是代表这两只虫能够交配, 就是默认异性, 问你在给出的关系中有没有与异性交配这一事实相反的, 即同性之间给出了交配 ...

  5. hdu 1829-A Bug's LIfe(简单带权并查集)

    题意:Bug有两种性别,异性之间才交往, 让你根据数据判断是否存在同性恋,输入有 t 组数据,每组数据给出bug数量n, 和关系数m, 以下m行给出相交往的一对Bug编号 a, b.只需要判断有没有, ...

  6. HDU 1829 A Bug's Life 【带权并查集/补集法/向量法】

    Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes ...

  7. hdu 1829 &amp;poj 2492 A Bug&#39;s Life(推断二分图、带权并查集)

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

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

    A Bug's Life POJ - 2492 Background Professor Hopper is researching the sexual behavior of a rare spe ...

  9. hdoj--1829--A Bug's Life(带权并查集)

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

随机推荐

  1. Java并发编程原理与实战八:产生线程安全性问题原因(javap字节码分析)

    前面我们说到多线程带来的风险,其中一个很重要的就是安全性,因为其重要性因此,放到本章来进行讲解,那么线程安全性问题产生的原因,我们这节将从底层字节码来进行分析. 一.问题引出 先看一段代码 packa ...

  2. @Resource,@Autowired,@Inject3种注入方式

    概况 @Resource,@Autowired,@Inject 这3种都是用来注入bean的,它们属于不同的程序中. ANNOTATION PACKAGE SOURCE @Resource javax ...

  3. c++模板函数作为参数的疑惑

    为什么22行只能传一个模板函数作为参数,而非模板却编译失败,求解释.

  4. CodeForces 816C 思维

    On the way to school, Karen became fixated on the puzzle game on her phone! The game is played as fo ...

  5. CodeForces - 1042B

    Berland shop sells nn kinds of juices. Each juice has its price cici. Each juice includes some set o ...

  6. weblogic 反序列化补丁绕过漏洞的一个批量检测shell脚本(CVE-2017-3248 )

    ~ 以下内容,仅供学习参考 ~ weblogic 反序列化补丁绕过漏洞已经出了两个月了,balabala ~~~ 废话不说,拿到该漏洞的利用工具weblogic.jar,但只能一个个检测ip和端口,效 ...

  7. Python练习-有点儿意思的用户登录

    Alex大神的需求(说实话他需求真特么多,真难满足他): 编写一个用户登陆接口:输入用户名密码,认证成功后显示欢迎信息,输错三次后锁定; # 编辑者:闫龙 #用户登录功能输入3次以上会被锁定:为了方便 ...

  8. OpenCV LIBTIFF_4.0 link errors

    以前用Caffe用的好好的,今天重装后居然报了很多这样的错误 /usr/lib/libopencv_highgui.so.' 1> /usr/lib/libopencv_highgui.so.' ...

  9. Python类相关的装饰器

    一.装饰器装饰类方法 from functools import wraps def wrapper(func): @wraps(func) def inner(self,*args,**kwargs ...

  10. php 中更简洁的三元运算符 ?:

    PHP 三元运算符是对参数赋值时候的一个简洁的主要用法. 一个主要的用法: PHP 三元运算符能够让你在一行代码中描述判定代码, 从而替换掉类似以下的代码: <?php if (isset($v ...