原题传送门
(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
");
else printf("N
");
}
}
return 0;
}