POJ 1182 食物链 (带权并查集 && 向量偏移)
题意 : 中文题就不说题意了……
分析 : 通过普通并查集的整理归类, 能够单纯地知道某些元素是否在同一个集合内。但是题目不仅只有种类之分, 还有种类之间的关系, 即同类以及吃与被吃, 而且重点是题目问的并不是种类是否在一个集合内, 而是考察给出的关系是否矛盾。在解释之前, 先明白一个问题, 对于给出的关系, 如果我不能通过前面的信息来推断出来, 是不是不能够判断现在给出关系的对错?那就将这个信息作为真命题并存储起来, 方便后面判断。有了刚刚前面的陈述, 可以知道两个东西=>
对于这个题目并查集存储的是关系(即同类或吃与被吃) && 只有能够相互之间确立关系的才能合并同一个集合内
那如何使用并查集存储关系呢?题目给出的是两个物种和它们间的关系, 我们可以将给出 的两个物种看成两个并查集的节点, 然后将连接两个节点的边带上相应的权值代表这两个节点之间的关系, 为了通俗和具体一点, 就举例说明, 例如题目给出 1 1 2 (即1和2是同类), 存储步骤以及图示如下

①用一个father数组来存储并查集内的父子关系, 这里用father[1] = 2将1设置为2的父节点。(常规并查集操作)
②用relation数组存储连接这两个点的权值(即关系)relation[1]=x, 这里的x需要进行定义, 这里定义如下 0=>同类、1=>父节点吃子节点、2=>子节点吃夫节点(这样的定义并非随意, 后面绿色文字有说明), 所以刚刚的式子就应该是relation[1]=0。
③知道了单独两个物种的关系, 那这两个物种就属于一个集合了。但是1和2有可能并非是单独的物种, 换句话说就是1和2在合并之前可能就已经属于某一个集合了, 刚刚前面也说到, 一旦在一个集合里面, 那这个集合里面的所有元素都能互相确立关系, 那1和2能够确定关系, 那原来1所在的集合肯定也能和2原来所在的集合之间所有的元素确立关系, 所以这两个集合需要合并!
④也就像刚刚③所说, 1和2有可能并非只是单独个体, 有可能已经和其他元素构成集合, 在合并的过程中, 还需要进行路径压缩才能发挥并查集的高效!
如果做完刚刚说的步骤, 那在每一次给出的关系就能通过并查集的查找来知道这句话是否有错!但是很明显, 因为有了权值的设置, 要进行③的集合合并和④的路径压缩就要同时考虑将relation数组进行相应的变化, 因为relation[k]记录的只是k与父节点的关系, 如果进行了路径压缩, 那relation[k]就要变成k与k所在集合根节点的关系了。接下来就是用到向量的地方了!以下来说说如何使用向量知识, 进行集合合并和路径压缩
集合合并:
如果输入=>R fir sec(fir物种和sec物种有R这种关系), 那我们可以得到的已知条件是 fir 和 sec 所在集合的根节点(假设已经经过路径压缩) Fir_root 和 Sec_root, 假设我们将Sec_root接到Fir_root上, 那就能得到如下图, 则我们所要求的就是红色箭头所指代的relation, 然后将节点进行常规的并查集合并, 就能完成集合合并操作了, 也就是relation[Sec_root] = (relation[fir]+(R-1)-relation[sec]+3)%3, father[sec_root] = fir_root, 这里再说明一下relation计算的式子, %3的原因是要保证值在0~2之间, 由于有-relation[sec]操作, 所以为了避免relation[sec]过大, 使得整条模三的式子为负数, 所以进行+3操作!这里需要注意的是, R只是题目的输入(即1或2), 而我们刚刚定义的relation的取值x只有三种情况, 两者的关系是什么呢?也就是如何用输入的R得到实际我们定义的x?如果输入R=1, 对应的x=0, 而R=2, 对应的x=1, 所以x = R-1就是当前物种fir和sec的关系, 这也就是刚刚说为什么x的那三个值并非随意定义的原因。

路径压缩:
操作呢, 就如下图所示, 可见除了根节点自己所有的节点最后的父亲都是根节点, 同样的, relation的更新也可以采用向量的知识, 代码就是可以先通过递归找到根结点, 然后代码中递归的过程就是下图①~④的过程, 是从根到末尾节点的更新, 具体看代码思考


至此就完成了所有操作, 只要在操作之前判断语句是否和之前给出的关系有矛盾, 具体的还是可以用向量来思考。
留下了递归进行路径压缩中如何变relation 和 判断是否是错误语句这两个问题, 看代码即可, 相信这个是不难思考的!
#include<stdio.h>
#include<iostream>
using namespace std;
;
int father[maxn], relation[maxn], n, k, nCase;
int findset(int x)//递归寻找根节点
{
if(x == father[x]) return x;
int temp = father[x];//temp == x的父节点
father[x] = findset(temp);//继续寻找根节点
relation[x] = ( relation[temp] + relation[x] )%;//通过向量相加可以得出现在x与根节点的关系
return father[x];
}
int main(void)£¬
{
scanf("%d %d", &n, &k);
; i<=n; i++){
father[i] = i;
relation[i] = ;
}
;
while(k--){
scanf("%d %d %d", &command, &fir, &sec);
|| sec<= || fir>n || sec>n) ans++;
&& fir==sec) ans++;
else{
int Fir_root = findset(fir);
int Sec_root = findset(sec);
if(Fir_root != Sec_root){//如果两个物种并不在一个关系, 也就是无法知道关系, 则合并
father[Sec_root] = Fir_root;
relation[Sec_root] = ( + (command - ) + relation[fir] - relation[sec] )%;
}else{
) {if(relation[fir] != relation[sec]) ans++;}//如果1就代表同类, 则fir和sec与根的关系应该是一样的
- relation[fir] + relation[sec])% != command- ) ans++;}//如果2就代表fir吃sec即command-1, 左边式子同样根据向量运算得到
}
}
}
printf("%d\n", ans);
;
}
POJ 1182 食物链 (带权并查集 && 向量偏移)的更多相关文章
- poj 1182 食物链 带权并查集
食物链是并查集的进阶运用的一道非常经典的题目. 题目如下: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A, ...
- POJ 2492 A Bug's Life (带权并查集 && 向量偏移)
题意 : 给你 n 只虫且性别只有公母, 接下来给出 m 个关系, 这 m 个关系中都是代表这两只虫能够交配, 就是默认异性, 问你在给出的关系中有没有与异性交配这一事实相反的, 即同性之间给出了交配 ...
- K - Find them, Catch them POJ - 1703 (带权并查集)
题目链接: K - Find them, Catch them POJ - 1703 题目大意:警方决定捣毁两大犯罪团伙:龙帮和蛇帮,显然一个帮派至少有一人.该城有N个罪犯,编号从1至N(N<= ...
- POJ - 2912 Rochambeau (带权并查集+枚举)
题意:有N个人被分为了三组,其中有一个人是开了挂的.同组的人的关系是‘=’,不同组的人关系是‘<’或'>',但是开了挂的人可以给出自己和他人任意的关系.现在要根据M条关系找出这个开了挂的人 ...
- A Bug's Life POJ - 2492 (带权并查集)
A Bug's Life POJ - 2492 Background Professor Hopper is researching the sexual behavior of a rare spe ...
- poj1182 食物链 带权并查集
题目传送门 题目大意:大家都懂. 思路: 今天给实验室的学弟学妹们讲的带权并查集,本来不想细讲的,但是被学弟学妹们的态度感动了,所以写了一下这个博客,思想在今天白天已经讲过了,所以直接上代码. 首先, ...
- POJ 1182 食物链(经典带权并查集 向量思维模式 很重要)
传送门: http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...
- poj 1182:食物链(种类并查集,食物链问题)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44168 Accepted: 12878 Description ...
- POJ 1182 食物链(种类并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 63592 Accepted: 18670 Description ...
随机推荐
- vue2 学习笔记
一.部署环境1.安装nodeJS -- 地址:https://nodejs.org/zh-cn/ 2.安装vue脚手架 (用于创建VUE项目的) 进入项目文件或者新建一个文件 npm install ...
- 20191224 Spring官方文档(Core 1.1-1.4)
1. IoC容器 1.1.Spring IoC容器和Bean简介 org.springframework.beans和org.springframework.context包是Spring框架的IoC ...
- python 并发编程 多线程 GIL与Lock
GIL与Lock Python已经有一个GIL来保证同一时间只能有一个线程来执行了,为什么这里还需要互斥锁lock? 锁的目的是为了保护共享的数据,同一时间只能有一个线程来修改共享的数据 GIT保证了 ...
- [转帖]Ubuntu 对应内核版本
带有相应Linux内核版本的Ubuntu版本列表 https://www.helplib.com/ubuntu/article_155943 问题: 是否有带有默认对应的Linux内核版本的Ubu ...
- js知识点——2之navigator
navigator(领航者) 1.appCodeName(返回浏览器的代码名) var x= navigator; document.write("CodeName:"+x.app ...
- python——列表方法
L.append():追加一个元素到列表末尾 L = [] L.append('boy') L.insert() :将一个元素插入到指定位置 L.insert(1, 'girl') L.extend( ...
- 手把手教你用Python搭建自己的量化回测框架【均值回归策略】
手把手教你用Python搭建自己的量化回测框架[均值回归策略] 引言 大部分量化策略都可以归类为均值回归与动量策略.事实上,只有当股票价格是均值回归或趋势的,交易策略才能盈利.否则,价格是随机游走的, ...
- HNUSTOJ-1621 Picking Cabbage(状态压缩DP)
1621: Picking Cabbage 时间限制: 2 Sec 内存限制: 32 MB提交: 26 解决: 14[提交][状态][讨论版] 题目描述 Once, Doraemon and N ...
- 反向传播算法-损失函数&激活函数
在监督学习中,传统的机器学习算法优化过程是采用一个合适的损失函数度量训练样本输出损失,对损失函数进行优化求最小化的极值,相应一系列线性系数矩阵W,偏置向量b即为我们的最终结果.在DNN中,损失函数优化 ...
- 一、bif
缩进是python的灵魂,缩进可以使python的代码整洁,有层次. python是脚本语言,就是为了简单方便以辅助科学运算,因此python有许多bif,build in function 全部都是 ...