当前位置: 首页 > article >正文

信息学奥赛一本通 1390:食物链【NOI2001】| 洛谷 P2024 [NOI2001] 食物链

【题目链接】

ybt 1390:食物链【NOI2001】
洛谷 P2024 [NOI2001] 食物链

【题目考点】

1. 种类并查集
2. 带权并查集

【解题思路】

解法1:种类并查集

已知有三类动物A、B、C。A吃B,B吃C,C吃A。
对于B类动物来说,A类动物是B类动物的天敌,C类动物是B类动物的猎物。
共有n个动物,对于动物 i i i,假设 i + n i+n i+n i i i的一个天敌,假设 i + 2 n i+2n i+2n i i i的一个猎物。( i + n i+n i+n i + 2 n i+2n i+2n是我们人为假设出来的并非1~n中任何动物的其他动物)
那么 i i i i + n i+n i+n i + 2 n i+2n i+2n分别可能是A、B、C中的哪类动物?有以下几种情况。

A类动物B类动物C类动物
i+nii+2n
ii+2ni+n
i+2ni+ni

设存在A、B、C三个集合,使用并查集表示这三个集合。那么调用find(i), find(i+n), find(i+2*n)就可以得到代表这三个集合的根结点的编号。

对于输入的动物编号x或y,如果x或y大于n,则该描述一定是假话

1. 如果输入1 x y,说x与y是同类
那么首先判断x与y是否是天敌与猎物的关系。

  • 判断x是否是y的天敌,也就是判断 x x x y + n y+n y+n是否在同一集合中find(x) == find(y+n)
  • 判断x是否是y的猎物,也就是判断 x x x y + 2 n y+2n y+2n是否在同一集合中find(x) == find(y+2*n)

只要满足上述两条件之一,那么x与y不可能是同类,这句话是假话。
如果不满足上述条件,那么x与y是同类,二者所在集合合并merge(x, y)
同时x的天敌与y的天敌是同类merge(x+n, y+n),x的猎物与y的猎物是同类merge(x+2*n, y+2*n)
2. 如果输入2 x y,表示x吃y,也就是x是y的天敌,y是x的猎物
如果x是y的猎物,或x与y是同类,则这句话是假话

  • 判断x是否y的猎物,也就是判断 x x x y + 2 n y+2n y+2n是否在同一集合中find(x) == find(y+2*n)
  • 判断x与y是否同类,也就是判断 x x x y y y是否在同一集合中find(x) == find(y)

只要满足上述两条件之一,那么x不可能是y的天敌,这句话是假话。
如果不满足上述条件,那么x与y的天敌是同类merge(x, y+n),x的天敌与y的猎物是同类merge(x+n, y+2*n),x的猎物与y是同类merge(x+2*n, y)

统计并输出假话的数量,即为最终结果。

解法2:带权并查集(待完善)

【题解代码】

解法1:种类并查集
#include<bits/stdc++.h>
using namespace std;
#define N 50005
int fa[3*N], ans;//fa[i]:i的双亲,下标1~3*n。 
void initFa(int n)
{
	for(int i = 1; i <= n; ++i)
		fa[i] = i;
}
int find(int x)
{
	return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y)
{
	fa[find(x)] = find(y);
}
int main()
{
	int n, k, op, x, y;
	cin >> n >> k;
	initFa(3*n);
	while(k--)
	{
		cin >> op >> x >> y;
		if(x > n || y > n)
		{
			ans++;
			continue;
		}
		if(op == 1)//x和y同类 
		{
			if(find(x) == find(y+n) || find(x) == find(y+2*n))
				ans++;
			else
			{
				merge(x, y);
				merge(x+n, y+n);
				merge(x+2*n, y+2*n);
			}
		}
		else//op == 2 x吃y 
		{
			if(find(x) == find(y+2*n) || find(x) == find(y))
				ans++;
			else
			{
				merge(x, y+n);
				merge(x+n, y+2*n);
				merge(x+2*n, y);
			}
		}
	}
	cout << ans;
	return 0;
}

http://www.kler.cn/a/524053.html

相关文章:

  • Java创建项目准备工作
  • 【llm对话系统】大模型 RAG 之回答生成:融合检索信息,生成精准答案
  • 网络工程师 (7)进程管理
  • 第十六届蓝桥杯大赛软件赛(编程类)知识点大纲
  • 基于dlib/face recognition人脸识别推拉流实现
  • 2025-01-28 - 通用人工智能技术 - RAG - 本地安装 DeepSeek-R1对话系统 - 流雨声
  • 通过 NAudio 控制电脑操作系统音量
  • 8638 直接插入排序
  • 9.7 打造你的专属智能助手:基于 GPT Builder 定制化 ChatGPT 应用全指南
  • 智能客服系统:结合 AI 模型与数据库实现对话与知识检索
  • FastAPI + GraphQL + SQLAlchemy 实现博客系统
  • DearMom婴儿车:书籍点亮希望,为乡村留守儿童架起知识桥梁
  • 【1.安装ubuntu22.04】
  • (四)线程 和 进程 及相关知识点
  • postgres基准测试工具pgbench如何使用自定义的表结构和自定义sql
  • Autogen_core:Concurrent Agents
  • 出现 Error processing condition on org.springframework.cloud.openfeign 解决方法
  • 线程局部存储tls的原理和使用
  • C++ 中用于控制输出格式的操纵符——setw 、setfill、setprecision、fixed
  • 智能化加速标准和协议的更新并推动验证IP(VIP)在芯片设计中的更广泛应用
  • vim交换文件的工作原理
  • 知网爬虫,作者、摘要、题目、发表期刊等主要内容的获取
  • 文章分类列表查询功能
  • 詳細講一下RN(React Native)中的列表組件FlatList和SectionList
  • 第25章 项目启航前的密谈
  • 基于容器本地化开发与交付的实践