洛谷题解P3367 【模板】并查集 暨 浅谈并查集

原题传送门

\(1\).定义

并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。————百度百科

\(2\).核心操作

\((1)\) .初始化

初始化的目的是把每个\(i\)的父亲都设为自己,为找父亲做准备

for(int i=1;i<=n;++i) fa[i]=i;

\((2)\) .找祖先(\(find\)

inline int find(int p){
	if(p==fa[p]) return p;      //搜到头了,即搜到了最初p的祖先
	return fa[p]=find(fa[p]);      //不断递归寻找(路径压缩)
}

注: \(fa[p]\) 表示 \(p\) 的父亲

\((3)\) .合并

//合并a,b;
fa[find(a)]=find(b);

即将一个节点的祖先的父亲指向另一个数的祖先。

上面的是并查集的基本操作。结合这个题,我们可以写出如下代码:
(基本上都是上面的模板)

\(Code\)

#include<iostream>
#include<cstdio>
using namespace std;
inline void read(int &x){
	int f=1;
	char ch=getchar();
	x=0;
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
int N,M;
int fa[200010];
int x[200010],y[200010],z[200010];
inline int find(int p){
	if(p==fa[p]) return p;
	return fa[p]=find(fa[p]);
}
int main(){
	read(N);read(M);
	for(int i=1;i<=N;i++) fa[i]=i;
	for(int i=1;i<=M;i++){
		read(z[i]);read(x[i]);read(y[i]);
		if(z[i]==1) fa[find(x[i])]=find(y[i]);
		else if(z[i]==2){
			if(find(x[i])==find(y[i])) printf("Y\n");
			else printf("N\n");
		}
	}
	return 0; 
}
posted @ 2020-10-17 20:15  _pwl  阅读(349)  评论(0编辑  收藏  举报
1 2 3
4