题目大意

  动物王国中有三类动物 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 句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

• 当前的话与前面的某些真的话冲突,就是假话

• 当前的话中 X 或 Y 比 N 大,就是假话

• 当前的话表示 X 吃 X,就是假话

你的任务是根据给定的 N 和 K 句话,输出假话的总数。

题解

  这道题我们用到了带权并查集。这种并查集的权值满足叠加性,也就是唯一存在一个函数f(a,b),使得结点cur与cur->Father->Father的关系=f(cur与cur->Father的关系,cur->Father与cur->Father->Father的关系)。这道题中,我们发现f(a吃b,b吃c)=a被吃c;f(a吃b,b被吃c)=a同类c;f(a被吃b,b同类c)=a吃c。我们令“吃”为1,“被吃”为2,“同类”为0,f(a,b)=(a+b)%3正好满足该要求。所以我们按照顺序尝试将命题涉及的两个动物加入并查集中,并判断是否为假话即可。

  以下我们将cur与cur->Father的关系简称为cur->ToFaRel。首先,如何压缩路径?明确情况:当FindRoot(cur->Father)后,cur->Father->Father==root。此时我们要让cur->Father=root。由f的定义,可得新的cur->ToFaRel = f(cur->ToFaRel, cur->Father->ToFaRel)。

  那么如何将两个集合合并呢?明确情况,结点a->Father==a的Root,b->Father==b的Root。明确目的,我们要让a->Father->Father=b->Father。由f的定义,a与b->Father的关系等于f(a与b的关系,b与b->Father的关系)=f(a与a->Father的关系,a->Father与b->Father的关系)。所以a->Father->ToFaRel = Rel(a,b)+b->ToFaRel-a->ToFaRel。判断是否合法也同理。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;const int MAX_NODE = 50010;struct UnionFindSet
{
private:struct Node{Node *Father;int ToFaRel;//relationship between this and father}_nodes[MAX_NODE];int _vCount;void Join(Node *a, Node *b, int toFaRel){a->ToFaRel = toFaRel;a->Father = b;}Node *FindRoot(Node *cur){if (cur->Father == cur)return cur;Node *root = FindRoot(cur->Father);Join(cur, root, (cur->ToFaRel + cur->Father->ToFaRel) % 3);return root;}public:UnionFindSet(int n){_vCount = n;for (int i = 1; i <= _vCount; i++)_nodes[i].Father = _nodes + i;}bool Join(int aId, int bId, int rel){Node *a = _nodes + aId, *b = _nodes + bId;Node *root1 = FindRoot(a), *root2 = FindRoot(b);if (root1 == root2)return (rel + b->ToFaRel) % 3 == a->ToFaRel;else{Join(root1, root2, ((rel + b->ToFaRel - a->ToFaRel) % 3 + 3) % 3);return true;}}
};int main()
{int n, opCnt, ans = 0;scanf("%d%d", &n, &opCnt);static UnionFindSet g(n);while (opCnt--){int op, a, b;scanf("%d%d%d", &op, &a, &b);if (a > n || b > n){ans++;continue;}else if (a == b && op == 2){ans++;continue;}switch (op){case 1:ans += !g.Join(a, b, 0);break;case 2:ans += !g.Join(a, b, 1);break;}}printf("%d\n", ans);return 0;
}

  

转载于:https://www.cnblogs.com/headboy2002/p/9427507.html

luogu2024 食物链相关推荐

  1. 【洛谷P2024】食物链

    题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种,但是我 ...

  2. [kuangbin带你飞]专题五 并查集 E - 食物链 (带权并查集)

    E - 食物链 题目链接:https://vjudge.net/contest/66964#problem/E 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C ...

  3. [bzoj4562][Haoi2016]食物链_记忆化搜索_动态规划

    食物链 bzoj-4562 Haoi-2016 题目大意:给你n个点,m条边的DAG,求所有的满足条件的链,使得每条链的起点是一个入度为0的点,中点是一条出度为0的点. 注释:$1\le n\le 1 ...

  4. 记忆优化搜索(简单题)(洛谷P3183 [HAOI2016]食物链 )( P5635 【CSGRound1】天下第一 )

    昨天做了蓝桥杯的时候,发现自己对于记忆优化搜索甚是不熟悉,所以今天随便找了几个基础题做做,顺便写下两片题解,顺便用了一下devc++敲的代码,发现没有代码补全真的可以说是灰常难受了... 洛谷P318 ...

  5. C - 食物链 POJ - 1182

    C - 食物链 POJ - 1182 大佬,%%% 加入给你一个 1, 那 1 应该放进 A.B.还是C呢,不知道了,所以开三倍的空间, 1~n 表示 A, n+1~2n 表示 B, 2n+1 ~ 3 ...

  6. POJ-1182 食物链(并查集)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 75814   Accepted: 22528 Description ...

  7. 食物链 poj 1182

    C - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  8. LuoguP3183 [HAOI2016]食物链 记忆化搜索

    题目描述 如图所示为某生态系统的食物网示意图,据图回答第1小题现在给你n个物种和m条能量流动关系,求其中的食物链条数.物种的名称为从1到n编号M条能量流动关系形如a1 b1a2 b2a3 b3.... ...

  9. 洛谷P3183食物链题解

    不得不说,这是道很难减少时间复杂度的题,且这个题有点像一道拓扑排序题,但是这个难度标签有点低. 我们应该可以想到拓扑排序可能是这个题的正解,但是题目中有输出总数,因此我们就可以造一个数组表示从这个点出 ...

最新文章

  1. mask rcnn训练自己的数据集
  2. 使用 jQuery 修改 DOM 方法
  3. 【转】sql server开启全文索引方法
  4. 无线宝服务器连接不上,无线网络连接不上怎么办 为什么无线网络连接不上
  5. 十万腾讯人,自救1000天
  6. docker容器的本地局域网yum源优化
  7. SAP UI5 OData框架里硬编码的80是怎么来的
  8. android代码画出波浪球,Android绘制波浪曲线,效果很赞的。
  9. iOS开发~UI布局(二)storyboard中autolayout和size class的使用详解
  10. 基于gateway网关实现限流
  11. 计算机硬件如何分类,计算机硬件分类教学.doc
  12. Linux运维问题解决(1)——Linux 定时任务 crontab 配置及示例
  13. python 基础 信息量很大很好,适合复习
  14. for循环语句例子 python_Python for循环语句一般形式例子
  15. Kafka数据迁移MaxCompute最佳实践
  16. Zynq7000硬件开发之硬件开发流程简介(二)
  17. RFC 5627 SIP中文翻译
  18. 虹科案例|基于SOLA光源的高通量Spike展示平台加速新冠病毒疫苗研制
  19. 原生小说APP源码出售,可二次开发,小说阅读app源码
  20. 华为电脑linux怎么切换输入法,华为平板键盘怎么切换中文输入法

热门文章

  1. kubeadm集群修改k8s证书时间到99年
  2. k8s部署hbase 2.2.6(含docker、helm部署方案)
  3. 爬有道翻译的几种方法
  4. SQLyog连接虚拟机中mysql8.0详解,2003、1130、2058错误码解决
  5. JDBC连接mysql、创建表、操作数据、PreparedStatement防注入、sql语句返回值类型知识汇总
  6. springboot中接口实例化_疫情爆发在家闲出屁的我,梳理一下SpringBoot知识点
  7. 使用Java8的Stream对两个 List 遍历匹配数据的优化处理
  8. Undefined function or method ' ' for input arguments of type 'double' ---错误解决办法
  9. c++ windows获得当前工作目录文件_使用命令行修改当前工作目录
  10. 内存位置访问无效_万字长文——java内存模型之volatile深入解读