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中的一种,但是我们并不知道它到 ...
随机推荐
- 解决python在cmd运行时导入包失败,出现错误信息 "ModuleNotFoundError: No module named ***"
1.下图为我的自动化测试工程结构图 我通过运行run.bat批处理文件,调用cmd控制台运行start_run.py来开始我的自动化测试,但是出现如下错误: 大家可能知道我们的工程在IDE(Pycha ...
- python入门pk小游戏
import time import random flag = True while flag: player_win = 0 enemy_win = 0 for i in range(1, 4): ...
- spring——aop详细总结1
AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补 ...
- C#添加带验证的websevice接口
记录一下,方便下次使用,或者能帮助到别人. 一.添加服务引用,输入WSDL文件地址. 二.代码 public TESTClient TestContext() { var binding = new ...
- C++单链表类(带头结点)
Link.h #ifndef _LINK_0411 #define _LINK_0411 #include <string> #include <iostream> //定义数 ...
- luogu1313计算系数题解--二项式定理
题目链接 https://www.luogu.org/problemnew/show/P1313 分析 二项式定理 \((a+b)^n=\sum_{k=0}^{n}{C^k_n a^k b^{n-k} ...
- Hash一致性算法底层原理
大纲 Hash取余算法 判定哈希算法好坏的四个定义 一致性Hash算法的两大设计 Hash取余算法 hash(Object.key)%N,hash值随Object.key.N的变化而变化. 如果有节点 ...
- 手工实现HttpBasic校验
HttpBasic: 是RFC中定义的一种控制HTTP协议访问资源的方式.具体当HTTP请求受限资源时,就需要在请求头中添加以"Authorization"为key的heade ...
- 如何使用classnames模块库为react动态添加class类样式
摘要 在react中添加动态的css时,传统的方式较为繁琐,今天刚好学习到一个模块库可以便捷的解决这个问题.对的,它就是“classnames”. classnames模块库 npm安装 npm in ...
- Python学习记录6-list、tuple、dict、set复习
数据类型在一门语言中是非常重要的,所以选择再次学习一下加深记忆.本次主要参考了大神廖雪峰的官方网站,非常感谢大神,讲的很清晰,收获很大. 标准数据类型 Number(数字) String(字符串) L ...