洛谷 P2024 [NOI2001]食物链(种类并查集,加权并查集)
传送门
解题思路
加权并查集:
什么是加权并查集?
就是记录着每个节点到它的父亲的信息(权值等)。
难点:在路径压缩和合并节点时把本节点到父亲的权值转化为到根节点的权值
怎么转化呢?
每道题都不一样QAQ
看一看这道题我们用r[x]=0表示是x和f[x]是同种生物,等于1表示x吃f[x],等于2表示x是f[x]的食物。
从x点到f[x]的权值更新为i点到祖宗的权值的方法:
由于路径压缩是递归实现,所以其实返回f[x]=find(f[x])时,f[f[x]]就是祖宗。
所以其实就是这样一张图:

然后放到这个题上,不难发现r[x]=(r[x]+r[f[x]])%3。
大胆猜想,无需证明!!
然后就是合并:
先放图吧!F1是A的祖宗,F2是B的祖宗。

把A和B合并起来(A的祖宗的父亲定为B的祖宗)本质上就是求r[f1]。
而x是知道了的——当A和B是同类时,x就是0,当A吃B时,x就是1。
所以很显然,r[f1]=(r[b]+x-r[a]+3)%3。(因为有可能出现负数,所以+3后再%3)
大胆猜想,无需证明!!
种类并查集:
对于种类并查集不了解的可以下看一下这道较为简单的题——团伙。
了解了种类并查集后,再来看看这道题:用三个并查集分别维护同类,食物,天敌(把f数组开三倍大小——1~n,n+1~2*n,n*2+1~3*n)。
对于每一次数据——
- 当1时:判断如果a的天敌是b或b的天敌是a就ans++,否则就合并(a的同类就是b的同类,a的食物就是b的食物,a的天敌就是b的天敌)
- 当2时:判断如果a和b同种或a的天敌是b就ans++,否则就合并(a的食物是b,a的同类是b的天敌,a的天敌是b的食物)
最后输出答案即可。
//写起来比较简单,思考简单,无挑战难度——by ckw
AC代码
加权并查集:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=;
int n,k,f[maxn],r[maxn],ans;
int find(int x){
if(f[x]==x) return x;
int fa=find(f[x]);
r[x]=(r[x]+r[f[x]])%;
f[x]=fa;
return fa;
}
int main()
{
cin>>n>>k;
for(int i=;i<=n;i++){
f[i]=i;
}
while(k--){
int a,b,c;
scanf("%d%d%d",&c,&a,&b);
if((c==&&a==b)||a>n||b>n){
ans++;
continue;
}
int fx=find(a);
int fy=find(b);
if(c==){
if(fx==fy&&r[a]!=r[b]){
ans++;
continue;
}
if(fx!=fy){
f[fx]=fy;
r[fx]=(+r[b]-r[a])%;
}
continue;
}
if(c==){
if(fx==fy&&(r[a]+-r[b])%!=){
ans++;
continue;
}
if(fx!=fy){
f[fx]=fy;
r[fx]=(+r[b]-r[a]+)%;
}
}
}
cout<<ans;
return ;
}
加权并查集
种类并查集(压行大法好):
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=;
int n,k,f[maxn*],ans;
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
int main()
{
cin>>n>>k;
for(int i=;i<=*n;i++){
f[i]=i;
}
while(k--){
int a,b,c;
scanf("%d%d%d",&c,&a,&b);
if(a>n||b>n){ans++;continue;}
if(c==) (find(a+n)==find(b)||find(b+n)==find(a))?(ans++):(f[find(a)]=find(b),f[find(a+n)]=find(b+n),f[find(a+n*)]=find(b+n*));
else (a==b||find(a)==find(b)||find(a)==find(b+n))?(ans++):(f[find(a)]=find(b+*n),f[find(a+n)]=find(b),f[find(a+*n)]=find(b+n));
}
cout<<ans;
return ;
}
种类并查集
//NOI2001 Day1 t1
洛谷 P2024 [NOI2001]食物链(种类并查集,加权并查集)的更多相关文章
- 洛谷 P2024 [NOI2001]食物链 解题报告
P2024 [NOI2001]食物链 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个 ...
- 洛谷 P2024 [NOI2001]食物链——带权值的并查集维护
先上一波题目 https://www.luogu.org/problem/P2024 通过这道题复习了一波并查集,学习了一波带权值操作 首先我们观察到 所有的环都是以A->B->C-> ...
- 洛谷 P2024 [NOI2001]食物链 (并查集)
嗯... 题目链接:https://www.luogu.org/problemnew/show/P2024 这道题和团伙这道题的思想比较类似,都是一个数组分成几个集合,但这道题的思路更加混乱,建议没做 ...
- 洛谷 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]食物链(种类并查集)
题目链接: https://www.luogu.org/problemnew/show/P2024 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 ...
- [洛谷P2024/POJ1182]食物链 - 带偏移量的并查集(2)
Description 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的 ...
- 种族并查集模板题分析 -----P2024 [NOI2001]食物链
本文参考了:洛谷p2024题解 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都 ...
- 【题解】P2024 [NOI2001]食物链 - 数据结构 - 并查集
P2024 [NOI2001]食物链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 动物王国中有三类动物 \(A,B ...
随机推荐
- 初学oracle第三天
体系结构 Oracle 采取的是 Client/Server 架构. 3.1 Client 3.1.1 Sqlplus 这是一个轻量级的功能强大的客户端, 是 dba 必须掌握的工具. 我们可以配 ...
- 【GDOI2016模拟4.22】总结
前言 早上,一进机房,发现所有人神情严肃,一股(\(da\))(\(ba\))场的气氛迎面扑来,我一下子意识到:nothing good! 这场比赛结果不是很好,50分: 第一题:感觉上是个神奇的匹配 ...
- KCF跟踪算法
参考:https://www.cnblogs.com/YiXiaoZhou/p/5925019.html 参考:https://blog.csdn.net/shenxiaolu1984/article ...
- SpringBoot路径映射
当然这个功能并非是springboot特有的,只是springboot提供了更简便的方法以供使用. 传统情况下我们跳转一个动态页面且并没有数据,也需要在controller中写一个跳转的con ...
- 前端面试题常考&必考之--清除浮动的方法
浮动 问题:子元素设置了float后,脱离父元素,导致父元素无法撑开?(也就是子元素的高度没有过渡到父元素) 例子: 检查元素的效果: (三种)常用的解决办法: 1>额外标签法,添加一个空的di ...
- qt学习(一)qt三个文件函数的框架
学到点什么, 而不是复制着什么, 每天敲着别人给的代码,苦涩得改完bug, 就这样一天天的过去, 实质上并没有学到什么, 别人的思想只是拿来借鉴, 你的思想是好是坏都是你的, 不用急着抛弃自己. 从q ...
- BZOJ 4923: [Lydsy1706月赛]K小值查询 Splay + 思维
Description 维护一个长度为n的正整数序列a_1,a_2,...,a_n,支持以下两种操作: 1 k,将序列a从小到大排序,输出a_k的值. 2 k,将所有严格大于k的数a_i减去k. In ...
- noi 1700 + 1756 八皇后问题 x
1700:八皇后问题 总时间限制: 10000ms 内存限制: 65536kB 描述 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方. 输入 无输入. 输出 按给定顺序和格式输出 ...
- cf 118B
B. Present from Lena time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- BM板子
BM线性递推 玄学玩意 struct LinearRecurrence { using int64 = long long; using vec = std::vector<int64>; ...