并查集学习笔记

并查集

是一种用于处理一些不相交的集合的合并与查询问题的树形数据结构
能够将两个集合合并 或者查询某个元素处于哪个集合中

基本操作代码

int find(int x){
	if(fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
void merge(int x,int y){
	fa[find(x)] = find(y);
	return;
}

例题一:P3367 【模板】并查集

思路:路径压缩并查集

例题二:P1892 [BOI2003] 团伙

思路:扩展域并查集板子

code
 #include <bits/stdc++.h>

using namespace std;
const int N = 2100;
int n,m,fa[N],u,v,ans;
char s;
int find(int x){
	if(fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
void merge(int x,int y){
	fa[find(x)] = find(y);
	return;
}
int main(){
	cin >> n >> m;
	for(int i = 1;i <= 2 * n;i++) fa[i] = i;
	for(int i = 1;i <= m;i++){
		cin >> s >> u >> v;
		if(s == 'F') merge(u,v);
		else{
			merge(v + n,u);
			merge(u + n,v);
		}
	} 
	for(int i = 1;i <= n;i++) if(fa[i] == i) ans++;
	cout << ans; 
	return 0;
}

例题三:P2024 [NOI2001] 食物链

思路:种类并查集,三倍并查集,注意特判与分类即可。

code
 #include <bits/stdc++.h>

using namespace std;
const int N = 1.5e5 + 10;
int n,k,fa[N],ans;
int find(int x){
	if(fa[x] == x) return x;
	return fa[x] = find(fa[x]);
}
int main(){
	cin >> n >> k;
	for(int i = 1;i <= 3 * n;i++) fa[i] = i;
	while(k--){
		int opt,u,v;
		cin >> opt >> u >> v;
		if(u > n || v > n){
			ans++;
			continue;
		}
		if(opt == 1){
			if(find(u + n) == find(v) || find(u) == find(v + n)) ans++;
			else{
				fa[find(u)] = find(v);
				fa[find(u + n)] = find(v + n);
				fa[find(u + 2 * n)] = find(v + 2 * n); 
			}
		}
		else{
			if(find(u) == find(v) || find(u) == find(v + n)) ans++;
			else{
				fa[find(u + n)] = find(v);
				fa[find(u + 2 * n)] = find(v + n);
				fa[find(u)] = find(v + 2 * n);
			}
		}
	}
	cout << ans;
	return 0;
}
posted @ 2023-10-13 21:11  LouYW07  阅读(11)  评论(0)    收藏  举报