并查集及经典问题
Quick-Find 算法
- 联通判断 O(1)
- 合并操作 O(n)
// 染色法class UnionSet {public:int *color, n;UnionSet(int n) : n(n) {color = new int[n + 1];for (int i = 0; i <= n; ++i) {color[i] = i;}}int find(int x) {return color[x];}void merge(int a, int b) {int cb = color[b];for (int i = 0; i <= n; ++i) {if (color[i] == cb) {color[i] = color[a];}}return;}};
Quick-Union 算法
联通判断 tree-height 树高
合并操作 tree-height 树高
优化
- 树的高度
- 节点数量
// 将连通关系转换为树形结构,通过递归的方式快速判定class UnionSet {public:int *boss, n;UnionSet(int n) : n(n) {boss = new int[n + 1];for (int i = 0; i <= n; ++i) {boss[i] = i;}}int find(int x) {if (boss[x] == x) { return x; }return find(boss[x]);}void merge(int a, int b) {int fa = find(a), fb = find(b);if (fa == fb) { return; }boss[fa] = fb;return;}};
Weighted-Quick-Union 算法
- 判断节点数量
- 通过考虑平均查找次数的方式,对合并过程进行优化
// 通过考虑平均查找次数的方式,对合并过程进行优化。class UnionSet {public:int *fa, *size, n;UnionSet(int n) : n(n) {fa = new int[n + 1];size = new int[n + 1];for (int i = 0; i <= n; ++i) {fa[i] = i;size[i] = 1;}}int find(int x) {if (fa[x] == x) { return x; }return find(fa[x]);}void merge(int a, int b) {int ra = find(a), rb = find(b);if (ra == rb) { return; }if (size[ra] < size[rb]) {fa[ra] = rb;size[rb] += size[ra];} else {fa[rb] = ra;size[ra] += size[rb];}return;}};
路径压缩 Weighted-Quick-Union 算法
- 把所有节点挂到根节点上(扁平化管理)
// 修改find操作class UnionSet {public :int *fa, *size, n;UnionSet(int n) : n(n) {fa = new int[n + 1];size = new int[n + 1];for (int i = 0; i <= n; i++) {fa[i] = i;size[i] = 1;}}int find(int x) {if (fa[x] == x) { return x; }int root = find(fa[x]);fa[x] = root;return root;}void merge(int a, int b) {int ra = find(a), rb = find(b);if (ra == rb) { return; }if (size[ra] < size[rb]) {fa[ra] = rb;size[rb] += size[ra];} else {fa[rb] = ra;size[ra] += size[rb];}return;}};
带路径压缩的并查集模板
class UnionFind {constructor(n) {this.boss = new Array(n).fill(0).map((val, ind) => ind);this.size = new Array(n).fill(1);}get(x) {return (this.boss[x] = this.boss[x] == x ? x : this.get(this.boss[x]));}merge(a, b) {this.boss[this.get(a)] = this.get(b);}}
并查集总结

