洛谷 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 ...
随机推荐
- 自定义指令 限制input 的输入位数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- 获取sender进程所产生的trace文件
直接开启数据库实例级别的sql_trace是不现实的,会对所有连接到oracle的session都产生sql_trace,这样会产生大量的trace文件(垃圾文件),因此为跟踪特定进程的sql信息,可 ...
- 正确重写hashCode方法
https://blog.csdn.net/HD243608836/article/details/87367763 到这里,对象写完了,开始描述问题. 计算hashCode的注意事项: 1.不能包含 ...
- Jdbc连接数据库基本步骤详解_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 Jdbc连接数据库的基本步骤,供大家参考,具体内容如下 package demo.jdbc; import java.s ...
- Centos7 离线安装 php7
问题:因内部管控,机器无法连接公有yum源安装php. 正常安装php7可以参考CentOS7.2 安装 PHP7.2 下面的代码也是一种方法 yum -y install libmcrypt lib ...
- Python3 面向对象-类的继承与派生
1.什么是继承? 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类可称为基类或超类,新建的类称为派生类和或子类. 子类会遗传父类的属性,从而解决代码重用问题. ...
- SQL server 字段合并CAST(org_no AS VARCHAR(20))+CAST(page_no AS VARCHAR(20))+CAST(djlb_no AS VARCHAR(20)))
sql server 字段合并(CAST) ---------------------- select (CAST(org_no AS VARCHAR(20))+CAST(page_no AS VAR ...
- 接口返回[object,Object]解决方法
1.我们请求接口时有时会返回[object,Object],[object,Object],[object,Object].... 这个我们使用JSON.stringfity(data),就可以解决.
- LOJ504「LibreOJ β Round」ZQC 的手办
https://loj.ac/problem/504 题解 对于区间取\(\max\),这个比较好办,直接在线段树上打标记就行了. 如果让我们弹出前\(n\)个数,我们可以用类似超级钢琴的思想,队列中 ...
- J - Mr.Panda and TubeMaster
题解 我们可以把每个格子拆成两个点,一个表示横向的,一个表示纵向的,相邻的格子横向和纵向连边. 如果直接按照题意做的话,我们应当在横向和纵向的点之间连边,有限制的边设下界为1,然后跑可行流. 或者考虑 ...