专栏文章
题解:P3367 【模板】并查集
P3367题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mipvq27u
- 此快照首次捕获于
- 2025/12/03 18:43 3 个月前
- 此快照最后确认于
- 2025/12/03 18:43 3 个月前
题解:洛谷 P3367 【模板】并查集
题目描述
给定
n 个元素(编号为 1 至 n),需要处理 m 次操作:- 操作1:合并元素
x和y所在的集合 - 操作2:判断
x和y是否属于同一集合
输入格式
- 第一行两个整数
n, m - 接下来
m行,每行三个整数z, x, y(z=1为合并,z=2为查询)
输出格式
- 对每个查询操作,输出一行
Y或N
算法思路
并查集核心操作
-
查询(Find)
- 递归查找根节点,并进行路径压缩优化
- 路径压缩:将路径上的所有节点直接指向根节点
-
合并(Union)
- 将两个集合的根节点连接
时间复杂度
- 单次操作平均复杂度:接近 O(1)
- 整体复杂度:O(m α(n)),其中 α(n) 为阿克曼函数的反函数
代码实现(不要抄啊)
CPP#include<bits/stdc++.h>
int father[220006];
int find(int k){//寻找
if(father[k]==k)return k;
return father[k]=find(father[k]);//边界
}
int main(){
int n,m;
std::cin>>n>>m;
for(int i=1;i<=n;i++){
father[i]=i;
}
for(int i=1;i<=m;i++){
int z,x,y;
std::cin>>z>>x>>y;
if(z==1){ // 合并根节点
father[find(x)]=find(y);
}
else{
if(find(x)==find(y)){
std::cout<<"Y"<<"\n";
}
else{
std::cout<<"N"<<"\n";
}
}
}
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...