title: 专题8 - 并查集
tags: [并查集]
categories: [OI, 算法专题]

模板

并查集用来处理连通块查询/合并,同时可以带权值来解决一系列问题。
并查集常见的优化手法有路径压缩/启发式合并/按秩优化,然而我只会前两个。
路径压缩注意到了一个连通块的父亲关系是由若干条单向链组成的,而在长链上做查找时间是被浪费的,在最坏的情况——树的结构是链时,单次查找就是O(n)的时间复杂度,且在做无用功。路径压缩将一条经过的长链在经过时顺手变成了若干条直接链接根节点的短链,从而避免额外功。然而这样的操作改变了树的结构,可能会带来新的问题。
启发式合并注意到小森林往往有更小的合并需求,因此记录每个森林大小,将小森林挂在大森林上。如何计算时间复杂度:考虑每个点,由于是小合并到大的,最无法利用这样的特点时,就是两个森林大小一样。这样一来,单个节点最多被处理log n次。由于有n个节点,时间复杂度就是O(n logn)。

路径压缩无权并查集

int fa[N];
int fnd(int u){
	if (fa[u] == u) return u; // 作为连通块root
	return fa[u] = find(fa[u]);
}
void merge(int u,int v,int r){  
    int fu = fnd(u),fv = fnd(v);  
    if (fu != fv){  
        fa[fu] = fv;
    }  
}