洛谷题解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;
}
本文欢迎转载,转载时请注明本文链接