动物王国中有三类动物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 带边权并查集)的更多相关文章

  1. [HDU 3712] Fiolki (带边权并查集+启发式合并)

    [HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[ ...

  2. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  3. AcWing 240. 食物链 | 并查集

    传送门 题目描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形. A吃B, B吃C,C吃A. 现有N个动物,以1-N编号. 每个动物都是A,B,C中的一种,但是我们并不知道它到底 ...

  4. AcWing 240. 食物链

    #include <iostream> using namespace std; ; int n, m; int p[N], d[N]; //p是baba,d是距离 int find(in ...

  5. [BZOJ 4668]冷战(带边权并查集+启发式合并)

    [BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...

  6. How Many Answers Are Wrong HDU - 3038 带边权并查集

    #include<iostream> #include<cstring> using namespace std; ; int d[N],p[N]; int find(int ...

  7. AcWing:239. 奇偶游戏(前缀和 + 离散化 + 带权并查集 + 异或性质 or 扩展域并查集 + 离散化)

    小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...

  8. POJ 1182 食物链(带权并查集)

    传送门 食物链  Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65579   Accepted: 19336 Descri ...

  9. 【POJ1182】 食物链 (带权并查集)

    Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...

随机推荐

  1. 怎样使当前cookie只有在加密协议https环境下才能将它发送到服务器

    使用 Secure 属性. 注意, 这个属性基本是"自动"的, 也就是说, 如果当前网页是https请求的, 那里面的各种HTTP请求的cookie都会自定加上这个属性, 如果当前 ...

  2. POJ 1789 Prim

    给定N个字符串,某个字符串转为另一个字符串的花费为他们每一位不相同的字符数. 求最小花费Q. Input 多组输入,以0结束. 保证N不超过2000. Output 每组输出"The hig ...

  3. zepto学习(一)之click事件和tap事件比较

    一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap分别 ...

  4. linux 文件操作与目录操作

    文件操作 使用命令 命令格式: 命令 [选项] [参数] [] 表示可选的 示例: ls -a /etc 常识命令 ls:查看指定目录的内容,不指定目录时查看当前工作目录 选项 说明 -a 显示所有文 ...

  5. STM32启动BOOT0 BOOT1设置方法

    原理图 启动方式 第一种启动方式是最常用的用户FLASH启动.默认启动方式 第二种启动方式是STM32内嵌的SRAM启动.该模式用于调试 第三种启动方式是系统存储器启动方式,不建议使用这种,速度比较慢 ...

  6. 解决织梦5.7添加新变量出现:Request var not allow!的办法

    找到:根目录->include->common.inc.phpif( strlen($svar)>0 && preg_match('#^(cfg_|GLOBALS|_ ...

  7. Spark集群任务提交流程----2.1.0源码解析

    Spark的应用程序是通过spark-submit提交到Spark集群上运行的,那么spark-submit到底提交了什么,集群是怎样调度运行的,下面一一详解. 0. spark-submit提交任务 ...

  8. Flutter——Image组件(图片组件)

    Image组件有很多构造函数,这里只说两个. Image.asset  本地图片 1.在根目录新建文件夹 /images 2.在 images 文件夹下建立两个文件夹 /images/2.0x  /i ...

  9. 《数据结构与算法之美》 <01>复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?

    我们都知道,数据结构和算法本身解决的是“快”和“省”的问题,即如何让代码运行得更快,如何让代码更省存储空间.所以,执行效率是算法一个非常重要的考量指标. 那如何来衡量你编写的算法代码的执行效率呢?这里 ...

  10. TensorFlow中numpy与tensor数据相互转化

    numpy与tensor数据相互转化: *Numpy2Tensor 虽然TensorFlow网络在输入Numpy数据时会自动转换为Tensor来处理,但是我们自己也可以去显式的转换: data_ten ...