食物链(带权并查集)
目录
题目描述
思路
完整代码
题目描述
动物王国中有三类动物 A,B,CA,B,C,这三类动物的食物链构成了有趣的环形。AA 吃 BB,BB 吃 CC,CC 吃 AA。
现有 NN 个动物,以 1 \sim N1∼N 编号。每个动物都是 A,B,CA,B,C 中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这 NN 个动物所构成的食物链关系进行描述:
- 第一种说法是
1 X Y
,表示 XX 和 YY 是同类。 - 第二种说法是
2 X Y
,表示 XX 吃 YY。
此人对 NN 个动物,用上述两种说法,一句接一句地说出 KK 句话,这 KK 句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
- 当前的话与前面的某些真的话冲突,就是假话;
- 当前的话中 XX 或 YY 比 NN 大,就是假话;
- 当前的话表示 XX 吃 XX,就是假话。
你的任务是根据给定的 NN 和 KK 句话,输出假话的总数。
输入格式
第一行两个整数,N,KN,K,表示有 NN 个动物,KK 句话。
第二行开始每行一句话(按照题目要求,见样例)
输出格式
一行,一个整数,表示假话的总数。
输入输出样例
输入 100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5
输出 3
思路
基本的并查集的概念和路径压缩等操作不多赘述,这里主要介绍一下带权并查集的概念。
带权并查集:在对并查集进行路径压缩和合并操作时,这些权值具有一定属性,即可将他们与父节点的关系,变化为与所在树的根结点关系。
我们用 dist[i] 表示 i 这个节点与其父节点权值关系。权值有三种:
- dist[i]% 3==0 表示这个节点与父节点是同类
- dist[i]%3==1 表示这个节点吃父节点
- dist[i]% 3==2 表示这个节点被父节点吃
如果我们知道A与B的关系,A与C的关系,那么我们必然可以推出B与C的关系。
所以,我们可以将表示当前这个节点与根节点的关系。若我们知道A与根的关系,B与根的关系,必然可以推出A与B的关系。
A与B的关系:(dist[A]- dist[B])%3
初始时,每个节点的根节点都是自己。因为初始时只清楚自己与自己的关系。
对每句话提到的两个节点,均做一遍查询根节点
int px = find(x);int py = find(y);
对x节点,查询根节点赋值给px,对y节点,查询根节点赋值给py。
若px !=py 表示x和y的根节点不同,根节点相同的我们才知道这两者之间的关系,所以之前是没有一句话说了x和y的关系的,不然我们肯定会把这两个并查集合并,根节点就会相同。那么我们把px的父亲指向py。那么x节点到现在的根节点的距离为:
dist[x]+dist[px]
若x 吃 y ,则:
(dist[x]+dist[px]-dist[y]-1)% 3==0
则:
dist[px]=dist[y]-dist[x]+1
若x 与 y 是同类,则:
(dist[x]+dist[px]-dist[y])% 3==0
则:
dist[px]=dist[y]-dist[x]
若px==py,表示x 和 y 的关系已由之前的话给出,只需相应判断就行。
在路径压缩时,需要同时更新dist[i]
int find(int x){if(x != p[x]){int u = find(p[x]);dist[x] += dist[p[x]];p[x] = u;}return p[x];
}
完整代码
完整代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>using namespace std;#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=j;i>=k;i--)typedef long long LL;const int N = 5e4 + 10;int n,m;int p[N];int dist[N];int find(int x){if(x != p[x]){int u = find(p[x]);dist[x] += dist[p[x]];p[x] = u;}return p[x];
}int main(){scanf("%d%d",&n,&m);rep(i,1,n) p[i] = i;int res = 0;while(m --){int t,x,y;scanf("%d%d%d",&t,&x,&y);if(x > n || y > n){res += 1;continue;}if(x == y && t == 2){res += 1;continue;}int px = find(x);int py = find(y);if(px != py){if(t == 1){p[px] = py;dist[px] = dist[y] - dist[x];}else{p[px] = py;dist[px] = dist[y] - dist[x] + 1;}}else{if(t == 1){if((dist[x] - dist[y]) % 3) res += 1;}else{if((dist[x] - dist[y] - 1) % 3) res += 1;}}}printf("%d",res);return 0;
}
食物链(带权并查集)相关推荐
- Acwing 240食物链(带权并查集)
AcWing 240.食物链 #include <iostream> using namespace std;//巧妙的利用余数的关系 //种类0 : d[x] % 3 == 0 //种类 ...
- POJ 1182 食物链 [并查集 带权并查集 开拓思路]
传送门 P - 食物链 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit ...
- ACM练级日志:带权并查集与食物链
最近终于干掉了高中两年都没有搞定的题目:食物链,就是那个A吃B,B吃C,C吃A这道NOI的经典题.当年自己写了200多行,把自己都写碎了,也没弄出来,最近学习了带权并查集,终于搞定了这道题. 首先说说 ...
- poj1182 and 携程预赛2第一题 带权并查集
题意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底 ...
- 【POJ - 1703】Find them, Catch them(带权并查集之--种类并查集 权为与父节点关系)
题干: Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 36176 Accep ...
- POJ 2912 Rochambeau(难,好题,枚举+带权并查集)
下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...
- 学习笔记——拓展域并查集和带权并查集
1,拓展域并查集 一般的并查集只能查找出各元素之间是否存在某一种相同的联系,如:a和b是亲戚关系,b和c是亲戚关系,这时就可以查找出a和c也存在亲戚关系.但如果存在多种相对的联系时一般的并查集就不行了 ...
- 2017乌鲁木齐区域赛I(带权并查集)
#include<bits/stdc++.h> using namespace std; int f[200010];//代表元 long long rl[200010];//记rl[i] ...
- BZOJ 2303 方格染色(带权并查集)
要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...
最新文章
- 封装echarts china map geo实现dispatch触发geoSelect事件高亮显示某个省份和城市,并定义复杂样式
- 如何避免重复提交?分布式服务的幂等性设计!
- oracle 数据有引号,oracle插入字符串数据时字符串中有'单引号问题
- 调整ViewState的位置,让你的asp.net页面对搜索引擎更友好
- Android ADB Server启动失败
- RHEL7 yum安装配置LAMP(Apache+PHP+MySql)服务器
- What?Java这么神奇的lambda表达式
- 两分钟彻底让你明白Android Activity生命周期(图文)!
- Ecilpse常用快捷键
- java循环1000000000_求十亿内所有质数的和,怎么做最快?
- Informatica的IDP理念:让业务部门成为真正数据受益者
- java星号心形代码_肿么用JAVA打印出心形的图案
- 案例分享——低压电力线载波通信模组(借助电源线实现远距离数据传输、宽压输入、波特率范围广、应用场景多样化)
- 蓝桥杯——等差素数列(c语言)
- Java TemplateProcessingException之Cannot execute subtraction: operands are null and #1234
- 前端element-ui中图片oss直传到阿里云
- matlab 光栅 傅里叶,【图像】【转帖】利用matlab绘制光栅条纹图像
- 算法篇-----粒子群算法
- js 通过图片链接获取file对象
- 正心,修身,方能齐家,治国,平天下
热门文章
- 【华人学者风采】林跃河 华盛顿州立大学
- uniapp开发微信小程序分享功能
- 粉条要经过什么检查才符合315?
- 1. Linux命令之ps:查看进程状态
- querylist V4 图片下载
- VBoxManage.exe: error: Failed to create the host-only adapter
- 原因: java.lang.NoClassDefFoundError: helloworld/Helloworld (wrong name: Helloworld)
- Linux alias编写
- LED显示行业之知识大全4
- 2023年电工杯B题详解