传送门


解题思路

加权并查集:

什么是加权并查集?

就是记录着每个节点到它的父亲的信息(权值等)。

难点:在路径压缩和合并节点时把本节点到父亲的权值转化为到根节点的权值

怎么转化呢?

每道题都不一样QAQ

看一看这道题我们用r[x]=0表示是x和f[x]是同种生物,等于1表示x吃f[x],等于2表示x是f[x]的食物。

从x点到f[x]的权值更新为i点到祖宗的权值的方法:

由于路径压缩是递归实现,所以其实返回f[x]=find(f[x])时,f[f[x]]就是祖宗。

所以其实就是这样一张图:

然后放到这个题上,不难发现r[x]=(r[x]+r[f[x]])%3。

大胆猜想,无需证明!!

然后就是合并:

先放图吧!F1是A的祖宗,F2是B的祖宗。

把A和B合并起来(A的祖宗的父亲定为B的祖宗)本质上就是求r[f1]。

而x是知道了的——当A和B是同类时,x就是0,当A吃B时,x就是1。

所以很显然,r[f1]=(r[b]+x-r[a]+3)%3。(因为有可能出现负数,所以+3后再%3)

大胆猜想,无需证明!!


种类并查集:

对于种类并查集不了解的可以下看一下这道较为简单的题——团伙

了解了种类并查集后,再来看看这道题:用三个并查集分别维护同类,食物,天敌(把f数组开三倍大小——1~n,n+1~2*n,n*2+1~3*n)。

对于每一次数据——

  • 当1时:判断如果a的天敌是b或b的天敌是a就ans++,否则就合并(a的同类就是b的同类,a的食物就是b的食物,a的天敌就是b的天敌)
  • 当2时:判断如果a和b同种或a的天敌是b就ans++,否则就合并(a的食物是b,a的同类是b的天敌,a的天敌是b的食物)

最后输出答案即可。

//写起来比较简单,思考简单,无挑战难度——by ckw

AC代码

加权并查集:

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. const int maxn=;
  5. int n,k,f[maxn],r[maxn],ans;
  6. int find(int x){
  7. if(f[x]==x) return x;
  8. int fa=find(f[x]);
  9. r[x]=(r[x]+r[f[x]])%;
  10. f[x]=fa;
  11. return fa;
  12. }
  13. int main()
  14. {
  15. cin>>n>>k;
  16. for(int i=;i<=n;i++){
  17. f[i]=i;
  18. }
  19. while(k--){
  20. int a,b,c;
  21. scanf("%d%d%d",&c,&a,&b);
  22. if((c==&&a==b)||a>n||b>n){
  23. ans++;
  24. continue;
  25. }
  26. int fx=find(a);
  27. int fy=find(b);
  28. if(c==){
  29. if(fx==fy&&r[a]!=r[b]){
  30. ans++;
  31. continue;
  32. }
  33. if(fx!=fy){
  34. f[fx]=fy;
  35. r[fx]=(+r[b]-r[a])%;
  36. }
  37. continue;
  38. }
  39. if(c==){
  40. if(fx==fy&&(r[a]+-r[b])%!=){
  41. ans++;
  42. continue;
  43. }
  44. if(fx!=fy){
  45. f[fx]=fy;
  46. r[fx]=(+r[b]-r[a]+)%;
  47. }
  48. }
  49. }
  50. cout<<ans;
  51. return ;
  52. }

加权并查集

种类并查集(压行大法好):

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. const int maxn=;
  5. int n,k,f[maxn*],ans;
  6. int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
  7. int main()
  8. {
  9. cin>>n>>k;
  10. for(int i=;i<=*n;i++){
  11. f[i]=i;
  12. }
  13. while(k--){
  14. int a,b,c;
  15. scanf("%d%d%d",&c,&a,&b);
  16. if(a>n||b>n){ans++;continue;}
  17. if(c==) (find(a+n)==find(b)||find(b+n)==find(a))?(ans++):(f[find(a)]=find(b),f[find(a+n)]=find(b+n),f[find(a+n*)]=find(b+n*));
  18. else (a==b||find(a)==find(b)||find(a)==find(b+n))?(ans++):(f[find(a)]=find(b+*n),f[find(a+n)]=find(b),f[find(a+*n)]=find(b+n));
  19. }
  20. cout<<ans;
  21. return ;
  22. }

种类并查集

//NOI2001 Day1 t1

洛谷 P2024 [NOI2001]食物链(种类并查集,加权并查集)的更多相关文章

  1. 洛谷 P2024 [NOI2001]食物链 解题报告

    P2024 [NOI2001]食物链 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个 ...

  2. 洛谷 P2024 [NOI2001]食物链——带权值的并查集维护

    先上一波题目 https://www.luogu.org/problem/P2024 通过这道题复习了一波并查集,学习了一波带权值操作 首先我们观察到 所有的环都是以A->B->C-> ...

  3. 洛谷 P2024 [NOI2001]食物链 (并查集)

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P2024 这道题和团伙这道题的思想比较类似,都是一个数组分成几个集合,但这道题的思路更加混乱,建议没做 ...

  4. 洛谷 P2024 [NOI2001]食物链

    题意简述 有人用两种说法对这 N 个动物所构成的食物链关系进行描述: 1."1 X Y",表示 X 和 Y 是同类. 2."2 X Y",表示 X 吃 Y . ...

  5. Java实现 洛谷 P2024 [NOI2001]食物链

    输入输出样例 输入 #1 100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5 输出 #1 3 import java.util.Scanner; pub ...

  6. P2024 [NOI2001]食物链(种类并查集)

    题目链接: https://www.luogu.org/problemnew/show/P2024 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 ...

  7. [洛谷P2024/POJ1182]食物链 - 带偏移量的并查集(2)

    Description 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的 ...

  8. 种族并查集模板题分析 -----P2024 [NOI2001]食物链

    本文参考了:洛谷p2024题解 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都 ...

  9. 【题解】P2024 [NOI2001]食物链 - 数据结构 - 并查集

    P2024 [NOI2001]食物链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 动物王国中有三类动物 \(A,B ...

随机推荐

  1. CentOS6.5 安装gitlab以及gitolite迁移gitlab

    CentOS6.5 安装gitlab以及gitolite迁移gitlab gitlab 的安装使用以及数据结构 安装 环境: CentOS6.5 基于 nignx + unicorn 搭建的应用环境, ...

  2. rocketmq设计

    # 设计(design) 1 消息存储 消息存储是RocketMQ中最为复杂和最为重要的一部分,本节将分别从RocketMQ的消息存储整体架构.PageCache与Mmap内存映射以及RocketMQ ...

  3. linux运维、架构之路-Hadoop完全分布式集群搭建

    一.介绍 Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS.HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件 ...

  4. 层定位layer

    一.如何实现层定位position属性 二.相对定位relative 三.绝对定位absolute 四.元素堆叠z-index 一.实现层定位的方法 position属性实现层定位,把元素分出层次形成 ...

  5. Golang在京东列表页实践总结

    Golang在京东列表页实践总结 作者:张洪涛 10余年软件开发和设计经验,曾就职于搜狐.搜狗.前matrixjoy公司联合创始人.甘普科技CTO. 目前线上状态 基于搜索实现: 全量数据,搜索结果不 ...

  6. winXP 系统下ubuntu-12.04 硬盘安装

    目地:实现XP ubuntu双系统,引导可选择. 出处:根查阅网络资料和自己的安装体检,记录如是. 系统版本:windowsXP  SP3   Ubuntu 12.04 工具资源:grup4dos 2 ...

  7. 手把手教你搞定个推iOS推送SDK集成

    以下是一位开发者在集成个推iOS推送SDK过程中的真实经历. 作者:Ezreallp 一次偶然的机会,公司的项目要用到推送,我自己本来就很懒,不愿意去弄整套APNS的流程,刚好之前跟朋友聊起过他们的产 ...

  8. uva live 7635 National Bomb Defusing Squad

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  9. 关于 Visual stdio 编译报错:error MSB6006: “CL.exe”已退出

    网上查看,原因有多种. 1,我自己遇到的是这样的: 环境:VS2019,编译项目 image-master,中间自己重整了原来的目录,移动了很多文件.编译报错:error MSB6006: “CL.e ...

  10. leetcode-mid-Linked list-160 Intersection of Two Linked Lists-NO

    mycode 用了反转链表,所以不符合题意 参考: 思路: 1 先让长的链表先走,然后相同长度下看是否相遇 class Solution(object): def getIntersectionNod ...