【算法4】1.5.union-find算法
1.5 union-find 算法
union-find 算法用于检查两个触点是否属于同一分量。
union-find 算法 API:
public class UF {
UF(int N); // 以整数标识(0 到 N-1) 初始化 N 个触点
void union(int p, int q); // 在 p 和 q 之间添加一条连接
int find(int p); // p 所在的分量的标识符
boolean connected(int p, int q); // p 和 q 是否属于同一个分量
}
- 初始化时,所有触点处于不同的分量
- 每添加一条连接 p-q 时,遍历数组,将属于 pid 的分量归并到 qid 的分量中
/**
* union-find 算法
* */
public class UnionFind {
private int[] id;
private int count;
public UnionFind(int N) {
id = new int[N];
for (int i = 0; i < N; i++) {
id[i] = i;
}
count = N;
}
public UnionFind(In in) {
this(in.readInt());
int N = count;
for (int i = 0; i < N; i++) {
union(in.readInt(), in.readInt());
}
}
// union-find 算法实现
public void union(int p, int q){
int pID = find(p);
int qID = find(q);
if (pID == qID) return;
for (int i = 0; i < id.length; i++) {
if (id[i] == pID) {
id[i] = qID;
}
}
count--;
}
public int find(int p) {
return id[p];
}
public boolean connected(int p, int q) {
return find(p) == find(q);
}
public int count() {
return count;
}
}
union-find 实现二:优化 union()
方法
- 初始化时,所有的触点属于不同的分量
- 每次添加一条连接 p-q 时,将 p 连接到 q 的分量中(即 id[p] = id[q]),分量的根触点 q[id] == q
// union-find 算法实现
public void union(int p, int q){
int pID = find(p);
int qID = find(q);
if (pID == qID) return;
id[pID] = id[qID];
count--;
}
// 从 id[p] 所属分量的根,即 id[p] = p
public int find(int p) {
while (id[p] != p) {
p = id[p];
}
return p;
}