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中的一种,但是我们并不知道它到 ...
随机推荐
- How does a browser know which response belongs to which request?
Today I knows that the server never send a request to a client! It just make response~ So,if the bro ...
- JSON运用在文件
#include <iostream>#include <fstream>#define JSON_IS_AMALGAMATION#include "json/jso ...
- Redis 的订阅发布(PUB/SUB)示例
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("127.0.0.1"); ISubscriber sub ...
- js中的函数提升和变量提升
变量提升和函数提升: 就是将变量声明或者函数全部代码提升到当前作用域(全局作用域或函数作用域)最开始的部分. JavaScript中函数域为最小域范围:for循环.while循环.if语句.switc ...
- SpringBoot--多环境部署配置文件
在resources 下创建 application-{profile}.properties 的配置文件,其中profile是任意名字: test:测试环境 prod:线上环境 pre-prod:预 ...
- ASP.NET如何接收清楚缓存的通知
1 如果使用cache的add方法或者接受CacheItemPriority值得Insert方法重载接收通知,可以提供CacheItemRemovedCallBack对象,选择在清除对象时接收通知 u ...
- SpEL表达式总结
前言SpEL(Spring Expression Language),即Spring表达式语言,是比JSP的EL更强大的一种表达式语言.为什么要总结SpEL,因为它可以在运行时查询和操作数据,尤其是数 ...
- Django学习:创建admin后台管理站点
Django自带一个后台管理站点,方便我们管理数据.这个界面只给管理员使用,并不对大众开放. 创建管理员用户 py manage.py createsuperuser 如下图所示: 用户名不填的话,默 ...
- shell 脚本检测端口状态
方法一: # cat check_port.sh #!/bin/bash cat ip.txt|while read line do /usr/bin/nc -w 1 -z $line > /d ...
- Ubuntu系统---安装搜狗输入法
Ubuntu_搜狗输入法 第一步: 1,下载搜狗输入法的安装包. 下载地址为:http://pinyin.sogou.com/linux/ ,如下图,要选择与自己系统位数一致的安装包,我的系统是64位 ...