POJ 1182 食物链

【并查集】POJ 1182 食物链 POJ 1182 : 食物链 由于题目中的N个动物都是A,B,C三类中的其中一种。题目有两种操作方式,【1】”1 X Y”,表示X和Y是同类,这个操作就是并查集中的【并】操作,【2】”2 X Y”,表示X吃Y,这个操作实际上是维护了森林中树之间的关系(类似有向图,此时树类比成一个顶点)。题目求这两个操作不成功的个数,假设为ans。 问题拆分 【1】进行1 X Y表示X和Y是同类... 阅读详情

传送门
这道题是典型的 带权并查集。
思想很巧妙,关键是怎么处理已有的事实来确定当前话的真假,关键是怎么存储已有事实,答案存储是在一颗颗边带权的树里,树是有向边,每条有向边上的权值表示上下结点的关系(也就是这两只动物的关系,到底是一样?还是A吃B?还是B吃A?)。如果当前话的两个动物属于不同的树,那么这句话一定为真的(因为这两个动物无法根据已有事实来链接起来关系)。当前话的两个动物只有属于同一颗树,我们才能有资格判断这句话是真的还是假的。
也就是说,每一棵树代表了一个独立的关系圈,如果查询的两个动物属于不同的关系圈,那么我们根本没有任何手段去判断真的假的,我们没有任何知识来推翻这句话,所以我们只能默认这句话是真的,为以后作准备。而且我们还要把这两个关系圈链接起来,使之成为一个关系圈。
现在,点明代码中涉及r[]数组的三处操作。

r[x] = (r[x] + r[pre[x]]) % 3;

  1. 这句是在find函数里的,我理解的是,r[]数组在赋值号左端时,代表当前节点与根节点的关系(此时当前节点的父节点一定或马上就是根节点!);r[]数组在赋值号右端时,代表与父节点的关系(当然,父节点可能就是根节点)。
    有点啰嗦,其实简单说,r[]数组表示的就是和父节点的关系,但是它被赋值时父节点一定是根节点(没有例外!)
    r[]数组的具体内容表示什么意思呢?0代表和父节点是同一种生物,1代表被父节点吃,2代表吃父节点。

    现在回到这句代码上,因为并查集的压缩规则,现在x要被链到根节点上,所以它的r[]也该更新了,它的旧的r[]表示和父节点的关系(但是现在父节点可能已经不是根节点了(因为在merge函数里改动)),在这句代码之前,它的父节点的递归调用已返回,父节点已经被链到根节点上且其r[]值已被更新。所以就是根据与父节点的关系以及父节点和根节点的关系来确定当前节点与根节点的关系,然后紧接着下一句当前节点被链到根节点上。
    再提一下这个递归,首先是从最底层当前查询节点出发,逐步向上,逐步递归调用,逐步压栈,直到找到根节点,然后开始递归返回,开始弹栈,开始向下,在返回的途中遇到的每一个点都把它链到根节点上(函数返回值就专门返回这个根)(返回时从上向下的第三个点开始真正有效)。
    至于这句的%3这个式子是怎么来的,自己写真值表找规律总结之,反正也没几种组合。

if (d == 1 && r[x] != r[y]) counter++;
if (d == 2 && (r[x] != 1 || r[y] != 2) && (r[x] != 0 || r[y] != 1) && (r[x] != 2 || r[y] != 0)) counter++;

  1. 这两句不会同时发生,所以没写else if,第二句的条件看起来有点晕,其实可以逆向求条件再取反。

if (r[y] == 0) r[fy] = r[x];
else if (r[y] == 1) r[fy] = (r[x] + 2) % 3; // fy 与 y 可能一样 必须 else if
else if (r[y] == 2) r[fy] = (r[x] + 1) % 3;

  1. 这三句是在fy子树被链到fx上且d=1时的发生的,d=1意味x和y是同一种动物,再枚举r[y]的值,fy和fx的关系就只剩由r[x]这个参数了来确定了,还是写真值表,做的时候得画图。
    注意当d=2时两种大情况的式子不一样,要重新推导,因为d=2是有偏向性的,指x吃y。
  2. 想一想为什么不怕fx,fy和x,y一样?设置r[]数组的同类关系为0以及r[]初始化为0是不是就有这种考量?
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

const int MAXN = 50005;
int N, K;
int pre[MAXN];
int r[MAXN];
int counter;

int find(int x)                  // 和hdoj 1829差不多,带权并查集
{
	if (pre[x] < 0) return x;
	int t = find(pre[x]);
	r[x] = (r[x] + r[pre[x]]) % 3;          //1
	return pre[x] = t;
}

void merge(int d, int x, int y)
{
	int fx = find(x);
	int fy = find(y);
	if (fx == fy)
	{
		if (d == 1 && r[x] != r[y]) counter++;     //2
		if (d == 2 && (r[x] != 1 || r[y] != 2) && (r[x] != 0 || r[y] != 1) && (r[x] != 2 || r[y] != 0)) counter++;
		return;
	}
	if (pre[fx] <= pre[fy])
	{
		pre[fx] += pre[fy];
		pre[fy] = fx;
		if (d == 1)
		{
			if (r[y] == 0) r[fy] = r[x];             //3
			else if (r[y] == 1) r[fy] = (r[x] + 2) % 3;       // fy 与 y 可能一样   必须 else if
			else if (r[y] == 2) r[fy] = (r[x] + 1) % 3;
		}
		else
		{
			if (r[y] == 0) r[fy] = (r[x] + 1) % 3;
			else if (r[y] == 1) r[fy] = r[x];
			else if (r[y] == 2) r[fy] = (r[x] + 2) % 3;
		}
	}
	else
	{     
		//
		pre[fy] += pre[fx];
		pre[fx] = fy;
		if (d == 1)
		{
			if (r[x] == 0) r[fx] = r[y];
			else if (r[x] == 1) r[fx] = (r[y] + 2) % 3;
			else if (r[x] == 2) r[fx] = (r[y] + 1) % 3;
		}
		else
		{
			if (r[x] == 0) r[fx] = (r[y] + 2) % 3;
			else if (r[x] == 1) r[fx] = (r[y] + 1) % 3;
			else if (r[x] == 2) r[fx] = r[y];
		}
		//
	}
}

int main()
{
	counter = 0;
	memset(pre, -1, sizeof pre);
	memset(r, 0, sizeof r);

	int d, x, y;
	scanf("%d%d", &N, &K);
	for (; K--;)
	{
		scanf("%d%d%d", &d, &x, &y);
		if (x > N || y > N || d == 2 && x == y)
		{
			counter++;
			continue;
		}
		merge(d, x, y);
	}
	printf("%d\n", counter);

	return 0;
}




//pre[fy] += pre[fx];
//pre[fx] = fy;
//if (d == 1)
//{
//	if (r[y] == 0) r[fx] = r[x];
//	else if (r[y] == 1) r[fx] = (r[x] + 2) % 3;
//	else if (r[y] == 2) r[fx] = (r[x] + 1) % 3;
//}
//else
//{
//	if (r[y] == 0) r[fx] = (r[x] + 1) % 3;
//	else if (r[y] == 1) r[fx] = r[x];
//	else if (r[y] == 2) r[fx] = (r[x] + 2) % 3;
//}
//if (r[fx]) r[fx] = r[fx] ^ 3;       // 得出对称的 关系式 要谨慎
//
//									// 其实这样写没啥意思,不如上面把x y反过来,直接写好
//									// 异或运算,^(0011),和0异或不变,和1异或取反
poj1182:食物链 题解 poj1182:食物链 听说是poj中最经典的一道并查集题目。我一做,果然很经典呢!好难啊!!!真的琢磨了很久才弄懂。这道题的重点就在于怎么用并查集表示题目中的关系环。 1. 题干 原题传送门1 原题传送门2 2. 思路详解 实际上,在做这道题之前,我对并查集的了解就只停留在权重选择和压缩路径上。也就是大家司空见惯的那种模板。顺带再默写一遍复习一下: #include <vector> using namespace std; class unionfind { public: 阅读详情

相关推荐

基于ENVI5.3的Landsat条带去除、辐射定标、大气校正

基于ENVI5.3的Landsat条带去除、辐射定标、大气校正坏带修复辐射定标大气校正 坏带修复 1.下载landsat_gapfill插件,放入“安装目录\Exelis\ENVI53\extensions”,重启ENVI 2. 加载拟处理文件(MTL.txt格式) 3.打开landsat_gapfill 4.选择存放位置并命名文件 5.选择处理文件 辐射定标 1.选择工具Radiometric Calibration 2.选择已修复坏带文件 3.修改参数,选择输出位置及命名文件 大气校正 1

u010198950的博客 1万+

POJ - 1182: 食物链 (并查集)

题目链接:http://poj.org/problem?id=1182 题目大意: 中文题目,自己看就好 解题思路:并查集经典中的经典题,在网上看了很多大牛的思路,大部分是增加一个结构体存动物间的关系,结合并查集判断,但是关系域的更新比较复杂,一下子不太容易理解,这里推荐一个大牛的解题思路,讲解得非常清楚:https://blog.youkuaiyun.com/niushuai666/article/de...

Jerry的博客 8105

3款主流AIGC模型部署方案对比:本地、云端与混合架构的成本与性能分析

本文对比分析了3种主流AIGC模型部署方案(本地、云端与混合架构)的成本与性能差异,帮助企业在预算、性能和维护复杂度之间找到最佳平衡点。通过实际案例和详细数据,展示了不同部署方式在延迟、扩展性、数据隐私等方面的优劣势,为技术决策者提供实用参考。

weixin_33158887的博客 370

POJ 1182:食物链 ← 种类并查集 快读

【问题描述】 动物王国中有三类动物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)当前的话与前

hnjzsyjyj的专栏 365

基于Playwright的雪球网股票情绪数据自动化采集实战

网络爬虫是自动化获取互联网公开数据的关键技术,其核心原理在于模拟浏览器行为或直接发送HTTP请求以解析网页内容。在金融科技与量化分析领域,实时、稳定的数据源具有极高的技术价值,能够为市场情绪分析、因子挖掘提供基础。面对采用动态加载、复杂反爬机制的现代单页应用,传统的请求库与Selenium方案在稳定性与隐蔽性上面临挑战。本文聚焦于利用Playwright这一现代浏览器自动化工具,通过模拟真实用户交互、监听网络请求,构建一个能够稳定采集雪球社区实时讨论热度的解决方案。该方案不仅解决了动态内容渲染问题,还通过请

weixin_42529328的博客 585

SpringBoot不用三方框架,怎么动态调度定时任务,ScheduledExecutorService 详解

Spring Boot 提供了强大的定时任务支持,无需依赖任何第三方框架,即可轻松实现可配置的定时任务。通过使用 `@EnableScheduling` 注解启用定时任务支持后,我们可以利用 `@Scheduled` 注解来定义定时任务的方法,这些方法可以在指定的时间间隔或特定时间点自动执行。 我们还可以通过集成 `ScheduledExecutorService` 来实现灵活的定时任务管理。`ScheduledExecutorService` 是 Java 标准库的一部分,能够以固定速率或延迟执行任务,

横竖撇折点 1938

【POJ No. 1182】 食物链

【POJ No. 1182】 食物链

代码改变世界 701

云计算学习——5G网络技术

华为eNSP网络设备模拟器的基础安装及简单使用

qq_42520799的博客 1445

POJ 1182-食物链

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

zzqwtc的博客 1848

高分六号GF-6 WFV数据处理全流程:从原始数据解压到经纬度投影转换

本文详细解析了高分六号GF-6 WFV遥感数据的完整处理流程。从原始数据解压与分块结构理解入手,指导如何安装ENVI国产卫星支持工具进行自动拼接,并重点阐述了利用RPC模型进行正射校正以消除几何畸变,以及将UTM投影转换为地理经纬度坐标的关键步骤。文章旨在帮助用户高效地将原始卫星数据转化为可直接用于农业监测、生态环境分析等领域的标准地理空间图像。

weixin_29047919的博客 196

基于YOLOv8的城市违建识别系统:从数据集构建到UI界面实现

YOLOv8是Ultralytics公司于2023年推出的最新一代YOLO(You Only Look Once)系列目标检测算法。更高效的骨干网络设计改进的锚框机制更精确的损失函数支持分类、检测、分割等多任务YOLOv8特别适合像违建识别这样的实时检测任务,能够在保持高精度的同时实现快速推理。

YOLO 674

POJ 1182 食物链(并查集) 详解

POJ 1182 食物链 (并查集) 详解参考做法比较经典的并查集的题目,主要是要理解路径压缩的过程。 用0 1 2 分别表示A B C的关系。 0吃1,1吃2,2吃0. 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。

chutzpah 2万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

poj 1182 食物链 并查集 Java

poj 1182 食物链 这道题其实还不是太明白 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; class UnionFind { int[] parent; int[] size; int count; public UnionFind(int n) {

weixin_46621409的博客 323

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

[POJ 1182]食物链[并查集]

题目链接:[POJ 1182]食物链[并查集] 题意分析: 动物间可能存在一种食物链x吃y,y吃z,z吃x。下面给出一些语句,判断有多少句是假话。 解题思路: 设置三个并查集,分别代表物种,同一并查集中的动物种类相同。 不同种类间的合并代表着捕食关系。例如 x, y。因为x可以为任意一个种类中的动物,所以在合并它们捕食关系时,我们要把所有的可能情况都合并起来。 什么时候说谎话呢? 1

闲停 559

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

POJ 1182 食物链 题解【并查集】

POJ 1182 食物链 题解【并查集】 题目链接:http://poj.org/problem?id=1182 ac代码: #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define N 150001 using namespace std; i...

qq_43979159的博客 213

POJ-1182 食物链

POJ-1182 食物链 题目链接:POJ-1182 题目大意:三种动物互克,给定关系说明是否是同类或者是否是互克关系,问有多少种非法情况 解题思路:最一开始想的是按照并查集的常规思路,并查集表示某种动物和某种动物是同类,然后弄一个集合储存相克关系,然后发展a吃b,b吃c,c吃a的自动转化判断太难做就放弃了,看了《挑战程序设计竞赛》之后发现例题做法是并查集储存事件,写不出比书籍更好的句子,所以看...

鱼头的水题之路 244

POJ——T 1182 食物链

http://poj.org/problem?id=1182 Time Limit:1000MS Memory Limit:10000K Total Submissions:77012 Accepted:22912 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, ...

agcozdwdfvds08078的博客 102

【POJ 1182 --- 食物链】

【POJ 1182 --- 食物链】 Description 动物王国中有三类动物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。 此...

来日浅谈的博客 522

poj 1182 食物链 //并查集

poj 1182 食物链 //并查集http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 99085 Accepted: 29983 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣...

Rshs 213

【CLASSICAL种类并查集】POJ 1182 食物链

POJ 1182 食物链 Description 动物王国中有三类动物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个动物...

L_X_ 176

POJ 1182 食物链(带权并查集)

POJ 1182 食物链(带权并查集) 前几天在叶某同学的忽悠下,做了这道挺有意思的题目,感觉这道有必要做下记录。刚开始想到大概是绕一个圈子来证明之前的关系是否与当前语句给出关系矛盾,若矛盾,则是假话(就是后来看别人博客的向量的方法,但是我只是有感觉,具体写不出,所以参考了下这位大神的博客:http://hi.baidu.com/tomspirit/item/d1f2a19b2aaf36d27...

wu2588的专栏 488

POJ 1182 食物链 【扩展域并查集】

动物王国中有三类动物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句话...

独钓门前月 360

POJ1182_食物链_并查集

唔,写了一晚上- -不只是写代码,我以为之前那个HDU4003我写的注释已经够多的了,没想到这次写的更多,果然写注释是会上瘾的- - 直接贴题和我自己的代码吧,题解神马的全在代码里,自认为自己这次写的还是比较清楚详尽和简洁的(自大啦-_-) 不过主要的核心思想用模三加法来加入并查集并不是我自己想出来的 食物链 Time Limit: 1000MS   M

u011343989的专栏 800

并查集怎么搞?POJ1182 食物链

文章目录并查集操作初始化查询元素的"祖先"查询元素是否同组合并POJ1182 食物链题解AC代码Tips 并查集 并查集是一种用来管理元素分组情况的数据结构。 可以进行如下操作: · 查询元素a和元素b是否属于同一组; · 合并元素a和元素b所在的组。 操作 初始化 int par[N], dth[N]; void init(int n) { for (int i = 0; i <= n; i++) { par[i] = i; dth[i] = 0;

Zoybzo想AK 223
上一篇: HDU 1532 Drainage Ditches
下一篇: HDU 2363 Cycling
Crossing over
博客等级 码龄10年 6粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值