博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj2492 A Bug's Life(带权并查集)
阅读量:4663 次
发布时间:2019-06-09

本文共 2155 字,大约阅读时间需要 7 分钟。

题目链接

题意

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

思路

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

代码

1 #include 
2 3 const int N = 2000 + 10; 4 int p[N]; 5 int r[N]; 6 7 void make_set(int n) 8 { 9 for (int i = 1;i <= n;i++)10 {11 p[i] = -1;12 r[i] = 0;13 }14 }15 16 int find_root(int x)17 {18 if (p[x] == -1) return x;19 20 int t = p[x];21 p[x] = find_root(p[x]);22 r[x] = (r[x] + r[t]) % 2;23 return p[x];24 }25 26 void union_set(int a, int b)27 {28 int ra = find_root(a);29 int rb = find_root(b);30 31 p[ra] = rb;32 r[ra] = (r[a] + r[b] + 1) % 2;33 }34 35 int main()36 {37 //freopen("poj2492.txt", "r", stdin);38 int t;39 scanf("%d", &t);40 int cnt = 0;41 while (t--)42 {43 int n, m;44 scanf("%d%d", &n, &m);45 make_set(n);46 bool flag = true;47 int a, b;48 for (int i = 0; i < m; i++)49 {50 scanf("%d%d", &a, &b);51 if (find_root(a) == find_root(b))52 {53 if (r[a] == r[b])54 {55 flag = false;56 continue;57 }58 }59 else union_set(a, b);60 }61 printf("Scenario #%d:\n", ++cnt);62 if (flag)63 puts("No suspicious bugs found!\n");64 else puts("Suspicious bugs found!\n");65 }66 return 0;67 }

分析

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

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、

转载于:https://www.cnblogs.com/sench/p/7944239.html

你可能感兴趣的文章
存储控制器、MMU、flash控制器介绍
查看>>
hdu-1814(2-sat)
查看>>
自我反省
查看>>
反射,得到Type引用的三种方式
查看>>
Objective-C数据类型之id,SEL,BOOL,nil,NULL和NSNull
查看>>
js获取网页屏幕可见区域高度
查看>>
Vector
查看>>
Linux添加新硬盘
查看>>
表格响应式布局实例
查看>>
离散数学第6版25页41题
查看>>
Servlet+JSP例子
查看>>
pc网页适配手机移动端的简单实现
查看>>
pl sql练习(2)
查看>>
Problem B: 判断回文字符串
查看>>
谷歌浏览器,添加默认搜索引擎的搜索地址
查看>>
shop--7.店铺编辑和列表--更新店铺的信息,包括对店铺照片的处理,根据shopId获取shop信息...
查看>>
数据结构化与保存
查看>>
C# .net 获取程序运行的路径的几种方法
查看>>
为什么需要Docker?
查看>>
国内5家云服务厂商 HTTPS 安全性测试横向对比
查看>>