算法竞赛备赛——【数据结构】并查集

并查集

普通并查集

注意根据数据大小来开int 或者 long long 否则容易MLE

树的存储结构 双亲表示法------数组 孩子表示法 孩子兄弟表示法

P3367 【模板】并查集 - 洛谷

C++ 复制代码
#include <bits/stdc++.h>
using ll=long long;
using namespace std;
const int N=2e5+5; 

int fa[N];
int n,m;

int find(int x){
	if(x==fa[x])
		return x;
	else return fa[x]=find(fa[x]);
} 
 
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;++i){
		fa[i]=i;
	}
	for(int i=0;i<m;++i){
		int z,x,y;cin>>z>>x>>y;
		if(z==1){
			//合并
			int fx=find(x);
			int fy=find(y);
			fa[fx]=fy;
		}else{
			//查询 
			int fx=find(x);
			int fy=find(y);
			if(fx==fy) cout<<"Y"<<endl;
			else cout<<"N"<<endl;
		}
	}
	return 0;
}

种类并查集

扩展域并查集 可描述敌对关系

敌人 朋友 没关系 扩展为2n

天敌 同类 猎物 没关系 扩展为3n

P1525 [NOIP 2010 提高组 关押罪犯 - 洛谷](https://www.luogu.com.cn/problem/P1525)

C++ 复制代码
#include <bits/stdc++.h>
using ll=long long;
using namespace std;
const int N=2e4+2; 

int f[2*N];
struct enemy{
	int a,b,c;
}e[100005];

bool cmp(enemy& e1,enemy& e2){
	return e1.c>e2.c; 
}

int find(int x){
	if(f[x]==x){
		return x;
	}
	else return f[x]=find(f[x]);
}

int main(){
	int n,m;cin>>n>>m;
	for(int i=1;i<=2*n;++i){
		f[i]=i;
	}
	for(int i=1;i<=m;++i){
		cin>>e[i].a>>e[i].b>>e[i].c;
	}
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=m;i++){
		int fa=find(e[i].a);
		int fb=find(e[i].b); 
		int fad=find(e[i].a+n);
		int fbd=find(e[i].b+n);
		if(fa==fb){
			cout<<e[i].c;
			return 0;
		}
		f[fa]=fbd;
		f[fb]=fad;
	}
	cout<<0<<endl;
	return 0;
}

P2024 [NOI2001 食物链 - 洛谷](https://www.luogu.com.cn/problem/P2024)

C++ 复制代码
#include <bits/stdc++.h>
using ll=long long;
using namespace std;
const int N=5e4+5; 

int f[3*N];

int find(int x){
	if(f[x]==x){
		return x;
	}
	else return f[x]=find(f[x]);
}

int main(){
	int n,k;cin>>n>>k;
	int ans=0;
	for(int i=1;i<=3*n;++i){
		f[i]=i;
	} 
	while(k--){
		int m,x,y;
		cin>>m>>x>>y;
		if(x>n||y>n||(m==2&&x==y)){
			ans++;
			continue;
		}
		int fx=find(x);//x同类 
		int fy=find(y);//y同类 
		int xenemy=find(x+n);//x天敌 
		int yenemy=find(y+n);//y天敌 
		int xeat=find(x+2*n);//x猎物 
		int yeat=find(y+2*n);//y猎物 
		if(m==1){
			if(xenemy==fy||yenemy==fx){
				ans++;
			}else{
				f[fx]=fy;
				f[xenemy]=yenemy;
				f[xeat]=yeat;		
			}
		}
		if(m==2){
			if(fx==fy||yeat==fx){
				ans++;	
			}else{
				f[fy]=xeat;
				f[yeat]=xenemy;
				f[yenemy]=fx;
			} 
		}
	}
	cout<<ans; 
	return 0;
}
相关推荐
_wyt00112 小时前
洛谷 B3930 [GESP202312 五级] 烹饪问题 题解
c++·gesp
通信小呆呆14 小时前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
benben04414 小时前
强化学习之DQN算法族(基于gymnasium开发)
算法
小小工匠15 小时前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾15 小时前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
何以解忧,唯有..15 小时前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang
想吃火锅100516 小时前
【leetcode】88.合并两个有序数组js
算法
один but you17 小时前
constexpr函数
c++
生成论实验室17 小时前
机器人:一个自主运动的系统
人工智能·算法·语言模型·机器人·自动驾驶·agi·安全架构