luogu2024 食物链
题目大意
动物王国中有三类动物 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;
}
luogu2024 食物链的更多相关文章
- luogu2024 食物链 (并查集)
		
把一个点拆成三个,分别对应它的同类.它的猎物和它的天敌,这样的话(以下的相等都是并查集意义上的): 如果令a,b同类,那么a的猎物不能是b的同类,a的天敌不能是b的同类 如果令a吃b,那么a的同类不能 ...
 - 关押罪犯 and 食物链(并查集)
		
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
 - NOI2001|POJ1182食物链[种类并查集 向量]
		
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65430 Accepted: 19283 Description ...
 - tyvj1202 数数食物链
		
描述 TsyD学习了生物的生态环境那一张后,老师留了一项作业,就是给一张食物网,求所有食物链的总数.(从最低营养级生物(它不能吃任何其他的生物)开始到最高营养级(它不能被任何其他生物吃) 叫做一条食物 ...
 - vijos1531 食物链
		
背景 安徽省芜湖市第二十七中学测试题 NOI 2001 食物链(eat) Description:OfficialData:OfficialProgram:JackDavid127 描述 动物王国中有 ...
 - poj1182食物链_并查集_挑战程序设计竞赛例题
		
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65534 Accepted: 19321 Description ...
 - BZOJ4562: [Haoi2016]食物链
		
Description 如图所示为某生态系统的食物网示意图,据图回答第1小题 现在给你n个物种和m条能量流动关系,求其中的食物链条数. 物种的名称为从1到n编号 M条能量流动关系形如 a1 b1 a2 ...
 - [poj1182]食物链(并查集+补集)
		
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64841 Accepted: 19077 Description ...
 - [并查集] POJ 1182 食物链
		
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 66294 Accepted: 19539 Description ...
 
随机推荐
- jdbc 使用谨记
			
jdbc是java操作数据库的杀手锏.所有java程序员,对jdbc应该都不陌生. 但是,应该你也曾经被其折磨的抓耳挠腮,咬牙切齿吧,也许正因为这样你才对其记忆犹新,刻骨铭心. 这里有一些使用jdbc ...
 - 白盒-CNN纹理深度可视化: 使用MIT Place 场景预训练模型
			
MIT发文:深度视觉的量化表示................ Places2 是一个场景图像数据集,包含 1千万张 图片,400多个不同类型的场景环境,可用于以场景和环境为应用内容的视觉认知任务. ...
 - Linux基础之网络协议
			
互联网通信原理 从物理层面来说,每台计算机在一开始都是彼此孤立的,为了实现信息的交流与共享,计算机之间必须要建立通信网络.例如人与人之间的交流,他们必须要共用一套语言系统,才能交流成功.计算机之间也是 ...
 - VS2015编译ffmpeg的问题解决
			
刚装了vs2015,打开一些ffmpeg项目,发现不能编译通过,包括stdio.h都无法找到,可能是vs2015的bug吧. 现在记录一下解决方法: 我的目录是这样定义的: C:\Program Fi ...
 - thinkphp里模版文件js无法使用if condition的问题
			
/** * @example thinkphp里模版文件js无法使用if condition的问题 * @example 参考地址:https://segmentfault.co ...
 - 44.bucket filter:统计各品牌最近一个月的平均价格
			
课程大纲 GET /tvs/sales/_search { "size": 0, "query": { "term": { &quo ...
 - 《零压力学Python》 之 第四章知识点归纳
			
第四章(决策和循环)知识点归纳 if condition: indented_statements [ elif condition: Indented_statements] [else: Inde ...
 - vue 中全局filter过滤器的配置及使用
			
在项目中使用到的经常用到过滤器,比如时间,数据截取等过滤器,如果在每个.vue中都可以复制同一个过滤器,这可以达到目的,但是遇到方法有bug时就需要诸葛修改进入不同的页面修改,这样既费时又费力,优先可 ...
 - 【codeforces 761E】Dasha and Puzzle
			
[题目链接]:http://codeforces.com/contest/761/problem/E [题意] 给你一棵树,让你在平面上选定n个坐标; 使得这棵树的连接关系以二维坐标的形式展现出来; ...
 - springMVC+springJDBC+Msql注解模式
			
最近基于Spring4.X以上的版本写了一个springMVC+springJDBC+Msql注解模式的一个项目,之中也遇到过很多问题 ,为了防止以后遇到同样问题现记录一下知识点以及详细配置. 首先我 ...