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

并查集

普通并查集

注意根据数据大小来开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;
}
相关推荐
木木子2212 小时前
# 密码强度检测深度解析:正则表达式实时分析、多维度评分算法与可视化反馈
mysql·算法·华为·正则表达式·harmonyos
Sw1zzle15 小时前
算法入门(四):二叉树 - 递归遍历三件套
算法·leetcode
万法若空16 小时前
【算法-查找】查找算法
java·数据结构·算法
海石16 小时前
子树怎么找?树的3种遍历方式来帮忙!
算法·leetcode
海石16 小时前
难度分 1588:思路 + 技巧 = AC
算法·leetcode
殳翰16 小时前
下服务器端开发流程及相关工具介绍(C++)
开发语言·c++
青瓦梦滋17 小时前
协议定制/序列化-反序列化(Linux视角)
linux·服务器·网络·c++
珠海西格电力19 小时前
云边端协同架构:零碳园区管理系统的技术底座
大数据·运维·人工智能·算法·架构·能源
山登绝顶我为峰 3(^v^)321 小时前
C/C++ 交叉编译方法
java·c语言·c++
还有多久拿退休金21 小时前
让飞书知识库跟着 commit 自己长:一套自动化知识库的真实实现
前端·算法·架构