并查集
维护"谁和谁是一伙的":find 找老大、join 合并两队,路径压缩让树变扁、查询接近 O(1)。
一、互动演示:合并 + 路径压缩
7 个点,每个指向自己的"老大"(父节点)。输入两点 join 合并;对某点 find 会把沿途节点直接挂到根(路径压缩)。
试试 join(1,2)、join(2,3),再 find(3) 看路径压缩。
二、参考代码(路径压缩)
int fa[MAXN];
void init(int n){ for(int i=1;i<=n;i++) fa[i]=i; } // 各自为王
int find(int x){
if(fa[x]==x) return x; // 找到根(大老板)
return fa[x] = find(fa[x]); // 路径压缩:沿途直接挂到根
}
void join(int x,int y){
int rx=find(x), ry=find(y);
if(rx!=ry) fa[rx]=ry; // 两个根合并
}
判断"同一集合":find(x)==find(y)。是 Kruskal 求最小生成树的核心零件。