leosana @ 2024-08-14 14:57:46
#include<iostream>
using namespace std;
const int maxn=1e4+5;
int fa[maxn];//存储父节点
int find(int x){//寻找某个数字的父节点
if(x==fa[x]) return x;
else return find(fa[x]);
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
fa[i]=i;//将每个数的父节点定义为本身
}
for(int i=1;i<=m;i++){
int x,y,z;
cin>>z>>x>>y;
if(z==2){
if(find(x)!=find(y)){
cout<<"N"<<endl;
}else{
cout<<"Y"<<endl;
}
}else{
fa[find(x)]=find(y);//将x与y的父节点合并
}
}
return 0;
}
by _____QWQ_____ @ 2024-08-14 15:01:12
要用路径压缩的,不然爬树太慢了 @leosana
by dyyzy @ 2024-08-14 15:01:41
@leosana 考虑并查集优化吧,你这个是
by _____QWQ_____ @ 2024-08-14 15:02:04
加一个赋值就可以了
#include<iostream>
using namespace std;
const int maxn=1e4+5;
int fa[maxn];//存储父节点
int find(int x){//寻找某个数字的父节点
if(x==fa[x]) return x;
else return fa[x]=find(fa[x]); ////直接把儿子连接到根节点上
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
fa[i]=i;//将每个数的父节点定义为本身
}
for(int i=1;i<=m;i++){
int x,y,z;
cin>>z>>x>>y;
if(z==2){
if(find(x)!=find(y)){
cout<<"N"<<endl;
}else{
cout<<"Y"<<endl;
}
}else{
fa[find(x)]=find(y);//将x与y的父节点合并
}
}
}
@leosana
by Cosine_Func @ 2024-08-14 15:04:02
@leosana 可以考虑随机合并优化(
by dyyzy @ 2024-08-14 15:05:23
或者考虑按秩合并
将
fa[find(x)]=find(y);//将x与y的父节点合并
改为
inline void merge(int u,int v){
u=get(u),v=get(v);
if(u==v)return;
if(sz[u]<sz[v])swap(u,v);
fa[v]=u,zs[u]+=sz[v];
}
其中 sz[]
维护了并查集节点个数
by qiuxiangyu2010 @ 2024-08-14 15:18:11
纯数组模拟了解一下:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[10010];
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
a[i]=i;
}
int z,x,y;
for(int i=1;i<=m;i++){
cin>>z>>x>>y;
if(z==1){
for(int j=1;j<=n;j++){
if(a[j]==a[y]&&j!=y){
a[j]=a[x];
}
}
a[y]=a[x];
}else{
if(a[x]==a[y]){
cout<<"Y\n";
}else{
cout<<"N\n";
}
}
}
return 0;
}
AC记录
by leosana @ 2024-08-14 18:04:00
AC了谢谢大家
by osmium_dust @ 2024-11-26 19:05:36
实测:cout改printf可以100