洛谷P2024 [NOI2001]食物链 种类并查集
洛谷P2024 [NOI2001]食物链
题目描述
\(n\le5*10^4\)
\(k\le10^5\)
Recollection
初中的时候想了一个假掉了的算法想了很久。
刚刚突然想起自己几次尝试这道题的想法有多么无知。
空を辿る路 足跡一つでも
追寻着天空的路上 只存留着我的足迹
この時のはてに貴方が若し居るなら
如果这个时候有你在我身旁的话
少しだけで好い 彷徨う私にも
哪怕只有一点点 即使是处于彷徨中的我
彼方から風の唄を届けて
也听见了从远方传来的风之歌
然后突然有点怆然……
Solution
先说那时的想法为什么假了吧。
只新开三个拓展的节点\(A=50011\),\(B=50012\),\(C=50013\)。
每次判断一个动物属于哪一种就看getf(i)==getf(A/B/C)。
当然,这是胡思乱想。因为很显然,每个动物没有实际的值\(ABC\),当然不能用这个来判断。
若第一个输入的点对就假设有一个为\(A\)种,也无法维持后续的间断的传递关系。
\(\dots\dots\)
还是不多说过往的愚昧了吧。
因为有三种动物,故开\(3*n\)的并查集。
这个并查集看作有三个维度,每一维都可以看做我们想要的主集。
那么为什么还要3倍的并查集呢?
因为除了想一般的并查集那样维护直接的传递关系,还要维护不同集合之间的传递"不在同一个集合"的关系。
那么结构上像极了余弦定理
b^2=a^2+c^2-2ac*cosB\\
c^2=a^2+b^2-2ab*cosC
\]
而我们的种类并查集也一样。
若\(x\),\(y\)属于同一集合,那么
f_{x+n}=f_{y+n}\\
f_{x+n+n}=f_{y+n+n}
\]
若\(x\)吃\(y\),那么
\]
美妙的三元变换呢!(雾
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#ifdef TH
#define debug printf("Now is %d\n",__LINE__);
#else
#define debug
#endif
using namespace std;
template<class T>inline void read(T&x)
{
char ch=getchar();
int fu;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
x*=fu;
}
inline int read()
{
int x=0,fu=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*fu;
}
int G[55];
template<class T>inline void write(T x)
{
int g=0;
if(x<0) x=-x,putchar('-');
do{G[++g]=x%10;x/=10;}while(x);
for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
}
int f[50010*3];
int n,k,ans;
int getf(int x)
{
if(x==f[x]) return x;
return f[x]=getf(f[x]);
}
void merge(int x,int y)
{
x=getf(x);
y=getf(y);
f[x]=y;
}
bool ask(int x,int y)
{
return getf(x)==getf(y);
}
int main()
{
n=read();
k=read();
for(int i=1;i<=n*3;i++) f[i]=i;
while(k--)
{
int op,x,y;
cin>>op>>x>>y;
if(x>n||y>n)
{
ans++;
continue;
}
if(op==1)
{
if(ask(x,y+n)||ask(x+n,y)) ans++;
else
{
merge(x,y);
merge(x+n,y+n);
merge(x+n+n,y+n+n);
}
}
if(op==2)
{
if(ask(x,y)||ask(x,y+n)||ask(x+n,y+n+n)) ans++;
else
{
merge(x+n,y);
merge(x+n+n,y+n);
merge(x,y+n+n);
}
}
}
cout<<ans;
return 0;
}
Memories
偶尔做做“水题”,也是不错的吧……但愿……
洛谷P2024 [NOI2001]食物链 种类并查集的更多相关文章
- 洛谷 P2024 [NOI2001]食物链 (并查集)
嗯... 题目链接:https://www.luogu.org/problemnew/show/P2024 这道题和团伙这道题的思想比较类似,都是一个数组分成几个集合,但这道题的思路更加混乱,建议没做 ...
- P2024 [NOI2001]食物链(种类并查集)
题目链接: https://www.luogu.org/problemnew/show/P2024 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 ...
- 洛谷 P2024 [NOI2001]食物链(种类并查集,加权并查集)
传送门 解题思路 加权并查集: 什么是加权并查集? 就是记录着每个节点到它的父亲的信息(权值等). 难点:在路径压缩和合并节点时把本节点到父亲的权值转化为到根节点的权值 怎么转化呢? 每道题都不一样Q ...
- 洛谷 P2024 [NOI2001]食物链 解题报告
P2024 [NOI2001]食物链 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个 ...
- 【题解】P2024 [NOI2001]食物链 - 数据结构 - 并查集
P2024 [NOI2001]食物链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 动物王国中有三类动物 \(A,B ...
- 洛谷 P2024 [NOI2001]食物链——带权值的并查集维护
先上一波题目 https://www.luogu.org/problem/P2024 通过这道题复习了一波并查集,学习了一波带权值操作 首先我们观察到 所有的环都是以A->B->C-> ...
- 洛谷 P2024 [NOI2001]食物链
题意简述 有人用两种说法对这 N 个动物所构成的食物链关系进行描述: 1."1 X Y",表示 X 和 Y 是同类. 2."2 X Y",表示 X 吃 Y . ...
- Java实现 洛谷 P2024 [NOI2001]食物链
输入输出样例 输入 #1 100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5 输出 #1 3 import java.util.Scanner; pub ...
- P2024 [NOI2001]食物链[扩展域并查集]
大水题一道啊,几分钟切掉. 还是扩展域,每个点拆3个点,之间连边表示有关系(即捕食关系).然后随便判定一下就好了,不难,毕竟NOI上古题目. #include<iostream> #inc ...
- NOI2001|POJ1182食物链[种类并查集 向量]
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65430 Accepted: 19283 Description ...
随机推荐
- osharp多租户方案
osharp多租户方案 租户信息 using System; using System.Collections.Generic; using System.Linq; using System.Tex ...
- 一次h5活动页面的踩坑 过程
托好奇心的福,这几天又接了一个bug,哦不,一个非常锻炼个人能力的h5页面,期间涉及到很多问题,在此打算先占个坑,等日后有时间再慢慢记录,无论是swiper插件的使用,还是关于硬件加速的运用,又或者是 ...
- linux xxx is not in the sudoers file. This incident will be reported.
前言 linux 报错:xxx is not in the sudoers file. This incident will be reported. 这意味着用户 xxx 没有在 sudoers 文 ...
- 什么是HTTP压缩及HTTP压缩的过程
HTTP压缩是指: Web服务器和浏览器之间压缩传输的"文本内容"的方法. HTTP采用通用的压缩算法,比如gzip来压缩HTML,Javascript, CSS文件. 能大大减少 ...
- Redis 原理 - Hash
Hash 数据结构 使用 ziplist 当同时满足下面两个条件时,使用 ziplist 存储数据 元素个数少于512个 (hash-max-ziplist-entries: 512) 每个元素长度小 ...
- 思绪碎片:一个INFP的自我对话
## 关于存在与意义 > "我写一些东西,不是为了让别人看见,而是为了未来的我." -- 阮一峰 - 未知带来的心慌持续蔓延 - **根本症结**:自身的弱小,无法坦然面对生 ...
- Envoy 学习笔记(一)
该系列学习笔记是作者为记录云原生基础架构学习过程而写.若想要详细学习 envoy,大家可以去 tetrate 官网和官方文档中学习. 如果没有任何接触云原生的经验,可以在学习相关概念前,去了解以下概念 ...
- Graph4Stream:基于图的流计算加速
作者:汪煜 之前在「姊妹篇」<Stream4Graph:动态图上的增量计算>中,向大家介绍了在图计算技术中引入增量计算能力「图+流」,GeaFlow流图计算相比Spark GraphX取得 ...
- MQTT消息传递过程中,序列化协议如何选择?文本序列化还是二进制序列化协议。
字符串消息的序列化 在上一篇文章中,我们使用MQTTnet 框架,实现了一个MQTT服务器.MQTT发布者进程.MQTT订阅者进程.在消息传递过程中,我们将控制台的字符串直接传递.因为MQTT是应用层 ...
- Clion配置Fortran环境
1.安装CLion 下载链接:https://www.jetbrains.com/ 下载好后安装到指定目录即可 2.安装Fortran插件 3.编写程序 1)打开CLion,新建一个Fortran项目 ...