并查集

1.将两个集合合并
2.询问两个元素是否在一个集合当中

基本原理:每个集合用一棵树来表示。树根的编号就是整个集合的编号。每个节点存储它的父节点,p[x]表示x的父节点。

问题1:如何判断树根:if(p[x] == x)
问题2:如何求x的集合编号:while(p[x]!=x)x=p[x]
问题3:如何合并两个集合:px是x的集合编号,py是y的集合编号。p[x] = y

当前问题用d[x]表示到它根节点的距离。由于有三种物种,

  1. 当x,y在同一集合中时,我们用(d[x] - d[y]) % 3 = 0来表示x,y为同类
  2. 当x,y在同一集合中时,我们用(d[x] - d[y] % 3 =1)来表示x吃y
  3. 当x,y在同一集合中时,我们用(d[x] - d[y] % 3 = 2)来表示y吃x

当两个物种不在同一集合中时,意味着还不能通过之前的话,来判断当前两个物种之间的关系,所以需要通过当前给的条件将这两个物种所在的集合合并。
合并时,当条件说明这两个物种是同类时,说明(d[x] - d[y] + ?) % 3=0, ?为两个集合根节点的距离。? = d[y] - d[x]
当条件说明这两个物种x吃y时,说明(d[x] + ? - d[y] - 1) % 3 = 0,故? = d[y] - d[x] + 1

问题描述

动物王国中有三类动物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≤50000,
0≤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

代码

#include<iostream>
using namespace std;
int p[50010],d[50010];
int find(int x){if(p[x] != x){int t = find(p[x]);d[x] += d[p[x]];p[x] = t;}return p[x];
}int main(){int n, m;cin >> n >> m;for(int i = 1; i <= n; ++i){p[i] = i;}int res = 0;while(m--){int t, x, y;cin >> t >> x >> y;if(x > n || y > n){res++;}else{int px = find(x), py = find(y);if(t == 1){if(px == py && (d[x] - d[y]) % 3 != 0){res++;}else if(px != py){p[px] = py;d[px] = d[y] - d[x];}}else{if(px == py && (d[x] - d[y] - 1) % 3a{res++; }else if(px != py){p[px] = py;d[px] = d[y] + 1 - d[x];}}}}cout << res << endl;return 0;
}

原题链接

算法:食物链(并查集)相关推荐

  1. Noi2001食物链-并查集

    Noi2001食物链-并查集 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #incl ...

  2. Kruskal算法与并查集

    Kruskal算法与并查集 一.Kruskal算法 1. 概念 Kruskal算法就是按照图中各个边上的权值大小进行递增排序,以此来构造最小生成树. 2.重点解析 在由Kruskal实现最小生成树的过 ...

  3. poj 1182 食物链 并查集

    转自一位大佬的最全题解 https://blog.csdn.net/c0de4fun/article/details/7318642 #include <cstdio> #include ...

  4. POJ 1182 食物链 [并查集 带权并查集 开拓思路]

    传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit  ...

  5. 简单易懂的并查集算法以及并查集实战演练

    文章目录 前言 一.引例 二.结合引例写出并查集 1. 并查集维护一个数组 2. 并查集的 并 操作 3. 并查集的 查 操作 4. 基本并查集模板代码实现--第一版(有错误后面分析) 4.1 Jav ...

  6. 算法总结 — 并查集

    参考:算法学习笔记(1) : 并查集 - 知乎 并查集 (disjoint set union) 是 最优美的数据结构之一 合并 (merge): 把两个集合合并 查找 (find): 查找一个元素的 ...

  7. 【算法】并查集的运用

    并查集的概念 朋友圈 团伙问题 连通图 总结 并查集的概念 并查集顾名思义就是合并和查找,问题在于合并什么,查找什么.这里有一种朴素的思想来解释这两个问题.就是把这个想成一棵树.合并什么?就是把不在这 ...

  8. 算法:并查集(四种方式)

    简单并查集 public class UnionFind {private int[] id;private int count;public UnionFind(int N) {count = N; ...

  9. Kruskal算法和并查集

    Kruskal算法 步骤: 第一步:给所有边按照从小到大顺序排列(直接使用库函数qsort / sort). 第二步:从小到大依次考察每条边(u,v),在执行第二步时会出现以下两种情况: 情况1:u和 ...

  10. Java实现_算法_并查集

    并查集 作用:用来查找某个图中是否含有闭环. 比如图一: 上图中就是没有闭环的一个图,而下图(图二)就是一个有闭环的图 思路1-数组寻根法: 顾名思义,数组寻根法(自己称呼的)就是寻找每个节点的根节点 ...

最新文章

  1. 皮一皮:这是结婚还是华山论剑...
  2. jsp页面引用相关js,css文件路径问题
  3. linux 下执行python.py 无效解决方案
  4. Android环境配置(Eclipse全开发环境下载)
  5. DEDECMS添加友情链接长度限制的详细解决方法
  6. 【智能制造】智能制造将势不可挡
  7. 3D标签云效果的实现
  8. Excel 中如何去掉数值中出现的 E +,网上的方法都试过了不管用,改变单元格格式等都无效
  9. 阿里P8、P9税后180W及以上到底是什么水平?
  10. 黑马程序员顺义校区php_PHP面向对象开发视频教程[黑马程序员]
  11. 基于Python小说电子书阅读系统设计与实现 开题报告
  12. 【原创】Xilinx:K7 DDR3 IP核配置教程
  13. 智能视频分析监控技术
  14. 后端文件流在浏览器pdf预览
  15. 网站服务器更新申请,网站服务器申请
  16. 产品经理必备的20个常用工具
  17. linux下的几种输入法下载地址
  18. VC操作word和excel文件,查询与读写[依赖office环境]
  19. AD20在pcb设计时,器件如何旋转特定角度
  20. 2021-2027全球与中国反射式空间光调制器市场现状及未来发展趋势

热门文章

  1. 【系统架构设计师】第一章:操作系统(1.2.2) 信号量与pv操作
  2. stack-es-标准篇-ElasticsearchClient-fields
  3. DRM之Microsoft PlayReady学习入门(一)
  4. ind2vec和vec2ind函数用法
  5. https://blog.csdn.net/qq_35992900/article/details/80673889
  6. K210 only support kmodel V3/V4 now
  7. 华为交换机配置接口安全
  8. 一行代码“黑”掉任意网站
  9. GK888CN与Devexpress报表打印标签
  10. 关于python类说法正确的是_关于Python的说法正确的是