01 | 并查集
并查集
并查集是一种树形数据结构,用于处理一些不相交集合的合并及查询问题。
常见的用途有求连通子图、求最小生成树的Kruskal算法和求最近公共祖先(LCA)等。
创建并查集只需要三个步骤。
算法步骤
- 初始化。把每个点所在集合初始化为其自身。
- 查找。查找两个元素所在的集合,即找祖宗。
- 合并。如果两个元素的集合号不同,将两个元素合并为一个集合。
注意
- 查找时,递归找祖宗,祖宗集合号等于本身时停止。回归时,把查找路径上的所有节点统一为祖宗的集合号。
- 合并时,只需要把一个元素的祖宗集合号改为另一个元素的祖宗集合号。“擒贼先擒王”,只改祖宗即可!。这是一个路径压缩的过程。
一个简单的小例子
#include <stdio.h> #define MAXN 255 int fa[MAXN]; /*用fa[]来表示集合号*/ void init(int n){ //初始化 for (int i = 1; i <= n; i++) { fa[i] = i; } } int find(int i) { //递归找祖宗 if (i == fa[i]) return i; else { fa[i] = find(fa[i]); //该步进行了路径压缩 return fa[i]; //返回父节点 } } void unionn(int a, int b) { //合并集合 int a_fa = find(a); // 找a 的祖宗p int b_fa = find(b); // 找b 的祖宗q fa[a_fa] = b_fa; // a的祖先指向b的祖先 } using namespace std; int main() { int n, m, x, y, q; scanf("%d", &n); //一共有n个人 init(n); scanf("%d", &m); //一共有m组关系 for (int i = 1; i <= m; i++) { scanf("%d %d", &x, &y); unionn(x, y); } scanf("%d", &q); for (int i = 1; i <= q; i++) { scanf("%d %d", &x,&y); if (find(x) == find(y)) printf("YES\n"); else printf("NO\n"); } return 0; }
算法复杂度
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)