【洛谷】P2024 [NOI2001] 食物链(扩展域并查集)

关键思路:扩展域并查集:

前提主观表明:fa[N]:  x,x+n为食物,x+n+n为天敌

0-n存储个体,n+1到2n存储食物,2n+1到3n存储天敌

图例:

 ACcode:

扩展域并查集
x,x+n代表x的敌人,x+n+n代表x的天敌 
#include<iostream>
using namespace std;
const int N=3*(5e4+10);
int fa[N];
int n,k,ans;
void init() {//初始化父节点 
	for(int i=1; i<=3*n; i++) {
		fa[i]=i;
	}
	return;
}
int find(int x) {//查找父节点 
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
//x,x+n==食物,x+n+n==天敌 
int main() {

	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);//输入"加速" 
	cin>>n>>k;
	init();
	for(int i=1; i<=k; i++) {
		int op,x,y;
		cin>>op>>x>>y;
		if(x>n||y>n) {//假话1 
			ans++;
			continue;
		}
		if(op==1){
			if(find(x+n)==find(y)||find(x+n+n)==find(y)){//不符合之前的推理,假话 
				ans++;
				continue;
			} 
			else{//合法 ,同类归并(同类每总都并) 
				fa[find(x)]=fa[find(y)];//x,y是同类 
				fa[find(x+n)]= fa[(find(y+n))];//那么他们的食物相同 
				fa[find(x+n+n)]=fa[find(y+n+n)];//那么他们的天敌相同 
			}
		}
		else{//x吃y ,不合理(题意是x吃y)假话 
			if(find(x+n+n)==find(y)||find(x)==find(y)){
				ans++;
				continue;
			}
			else{//合法 
				fa[find(x+n)]=fa[find(y)];//y是x的食物 
				fa[find(x+n+n)]=fa[find(y+n)];//y的食物是x的天敌 
				fa[find(y+n+n)]=fa[find(x)];//循环回来y的天敌是x,很合理操作 
			}
		}
	}
	cout<<ans;//结果 
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值