AcWing:240. 食物链(扩展域并查集 or 带边权并查集)
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。
A吃B, B吃C,C吃A。
现有N个动物,以1-N编号。
每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述:
第一种说法是”1 X Y”,表示X和Y是同类。
第二种说法是”2 X Y”,表示X吃Y。
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。
当一句话满足下列三条之一时,这句话就是假话,否则就是真话。
1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。
你的任务是根据给定的N和K句话,输出假话的总数。
输入格式
第一行是两个整数N和K,以一个空格分隔。
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。
若D=1,则表示X和Y是同类。
若D=2,则表示X吃Y。
输出格式
只有一个整数,表示假话的数目。
数据范围
1≤N≤500001≤N≤50000,
0≤K≤1000000≤K≤100000
输入样例:
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
输出样例:
3
题解:
扩展域并查集:我们把每个动物拆成3个节点,分别是同类域xself,捕食域xeat,天敌域xenemy。
#include <iostream>
#include <cstdio> using namespace std; const int maxn = 3e5+; int f[maxn]; int get(int x) {
if(x == f[x]) {
return f[x];
}
int root = get(f[x]);
return f[x] = root;
} int main() {
int n, m;
scanf("%d %d", &n, &m);
for(int i = ; i <= * n; i++) {
f[i] = i;
}
int ans = ;
while(m--) {
int op, x, y;
scanf("%d %d %d", &op, &x, &y);
int x_self = x, x_eat = x + n, x_enemy = x + n + n;
int y_self = y, y_eat = y + n, y_enemy = y + n + n;
if(x > n || y > n) { //动物编号不存在
ans++;
} else if(op == ) { //x和y是同类关系
if(get(x_eat) == get(y_self) || get(x_self) == get(y_eat)) { //如果x捕食的物种和y的同类在同一集合,或者x的同类和y捕食的物种在同一集合,那么不成立,此话是假
ans++;
} else { //合并同类物种
f[get(x_self)] = get(y_self);
f[get(x_eat)] = get(y_eat);
f[get(x_enemy)] = get(y_enemy);
}
} else { //x和y是捕食关系,x吃y
if(get(x_self) == get(y_self) || get(x_self) == get(y_eat)) { //如果x的同类和y的同类在同一集合,或者x的同类和y捕食的物种在同一集合,那么不成立,此话是假
ans++;
} else { //合并同类物种
f[get(x_eat)] = get(y_self);
f[get(x_self)] = get(y_enemy);
f[get(x_enemy)] = get(y_eat);
}
}
}
printf("%d\n", ans);
return ;
}
带边权并查集:
看这篇优秀的博客,里面解释的很清楚:https://blog.csdn.net/linkfqy/article/details/69055713
#include <iostream>
#include <cstdio> using namespace std; const int maxn = 5e4+; int f[maxn];
int d[maxn]; int get(int x) {
if(x == f[x]) {
return f[x];
}
int root = get(f[x]);
d[x] += d[f[x]];
return f[x] = root;
} int main() {
int n, m;
scanf("%d %d", &n, &m);
int ans = ;
for(int i = ; i <= n; i++) {
f[i] = i;
d[i] = ;
}
while(m--) {
int x, y, w;
scanf("%d %d %d", &w, &x, &y);
if(x > n || y > n || (w == && x == y)) {
ans++;
continue;
}
int fx = get(x);
int fy = get(y);
if(fx == fy) {
if(((d[x] - d[y]) % + ) % != w - ) {
ans++;
}
} else {
f[fx] = f[fy];
d[fx] = d[y] + (w - ) - d[x];
}
}
printf("%d\n", ans);
return ;
}
AcWing:240. 食物链(扩展域并查集 or 带边权并查集)的更多相关文章
- [HDU 3712] Fiolki (带边权并查集+启发式合并)
[HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[ ...
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
- AcWing 240. 食物链 | 并查集
传送门 题目描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形. A吃B, B吃C,C吃A. 现有N个动物,以1-N编号. 每个动物都是A,B,C中的一种,但是我们并不知道它到底 ...
- AcWing 240. 食物链
#include <iostream> using namespace std; ; int n, m; int p[N], d[N]; //p是baba,d是距离 int find(in ...
- [BZOJ 4668]冷战(带边权并查集+启发式合并)
[BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...
- How Many Answers Are Wrong HDU - 3038 带边权并查集
#include<iostream> #include<cstring> using namespace std; ; int d[N],p[N]; int find(int ...
- AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)
小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...
- POJ 1182 食物链(带权并查集)
传送门 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65579 Accepted: 19336 Descri ...
- 【POJ1182】 食物链 (带权并查集)
Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...
随机推荐
- Sql Server 收缩日志文件原理及always on 下的实践
一.准备知识 1.LSN LSN用来标识特定日志在日志文件中位置(详情请见什么是LSN:日志序列号),它由两部分组成:一部分用来标识VLF(虚拟日志文件)的序列号,剩下的用来标识该日志在VLF中的具体 ...
- el-table 单元格样式修改
<el-table :cell-style="set_cell_style"> set_cell_style({row, column, rowIndex, colum ...
- MyEclipse的Server标签出现:Could not create the view: An unexpected exception was thrown
删除工作空间下的.metadata\.plugins\org.eclipse.core.runtime\.settings\com.genuitec.eclipse.ast.deploy.core.p ...
- UEditor编辑器
1.UEditor编辑器官网:http://ueditor.baidu.com/website/ 2.下载文件:选择 1.4.3.3 .Net版本 UTF-8板 3.建一个ueditor文件夹,将下 ...
- bootstrap-table的简单使用
先上效果图: 第一步:引用bootstrap-table的样式和js. @Styles.Render("~/assets/css/bootstrap.css") @Styles.R ...
- javaScript节流与防抖
一.节流(throttle) 用来实现阻止在短时间内重复多次触发同一个函数.主要用途:防止使用脚本循环触发网络请求的函数的恶意行为,确保请求的真实性(当然也包括其他阻止高频触发行为的应用): 实现原理 ...
- 解决微信小程序Date.parse()获取时间戳IOS显示为NaN
ios系统不支持2018-03-29这样格式的时间导致出现的这个问题, IOS只识别2018/03/09这样的格式. 上正则 //之前的var data = '2018-03-09 12:00:00' ...
- 升级openssh到高版本
linux升级openssh到高版本 可以解决OpenSSH 安全漏洞(CVE-2018-15919)和SSH服务器类型和版本 如果是新服务器,需要安装对应命令vim 上传下载等命令 安装上传或者下载 ...
- Oracle对字段去重查询所有字段数据
单个字段: select distinct(a) from tableA; 多个字段,利用max()去重 SELECT * FROM GM_PPU_RESIDENT_NORBASE g WHE ...
- java之JVM学习--简单理解编译和运行的过程之概览
java代码编译流程图: java字节码执行由JVM执行引擎完成 Java代码编译和执行的整个过程包含了以下三个重要的机制: Java源码编译机制 类加载机制 类执行机制 Java源码编译机制 Jav ...