Union —— 找到两个元素所在集合的两个老大哥 A 和 B, 将其中一个老大哥的父指针指向另外一个老大哥
Time 都是 O(log* n),约等于 O(1)
功能
合并两个集合
查询某个元素所在集合
判断两个元素是否在同一个集合
获得某个集合的元素个数
统计当前集合个数
跟连通性有关的问题,都可以使用 BFS 和 Union Find
什么时候无法使用 Union Find?
需要拆开两个集合的时候无法使用Union Find
示例一 - 判断两个点是否联通
public class ConnectingGraph {
/*
* @param n: An integer
*/
private int[] father;
public ConnectingGraph(int n) {
// do intialization if necessary
father = new int[n + 1];
for (int i = 1; i <= n; i++) {
father[i] = i;
}
}
private int find(int x) {
if (father[x] == x) {
return father[x];
}
father[x] = find(father[x]);
return father[x];
}
/*
* @param a: An integer
* @param b: An integer
* @return: nothing
*/
public void connect(int a, int b) {
// write your code here
int root_a = find(a);
int root_b = find(b);
if (root_a != root_b) {
father[root_a] = root_b;
}
}
/*
* @param a: An integer
* @param b: An integer
* @return: A boolean
*/
public boolean query(int a, int b) {
// write your code here
return find(a) == find(b);
}
}
示例二 - 返回联通块大小
public class ConnectingGraph2 {
/*
* @param n: An integer
*/
int[] father;
int[] size;
public ConnectingGraph2(int n) {
// do intialization if necessary
father = new int[n + 1];
size = new int[n + 1];
for (int i = 1; i <= n; i++) {
father[i] = i;
size[i] = 1;
}
}
/*
* @param a: An integer
* @param b: An integer
* @return: nothing
*/
private int find(int x) {
if (father[x] == x) {
return father[x];
}
father[x] = find(father[x]);
return father[x];
}
public void connect(int a, int b) {
// write your code here
int root_a = find(a);
int root_b = find(b);
if (root_a != root_b) {
father[root_a] = root_b;
size[root_b] += size[root_a];
}
}
/*
* @param a: An integer
* @return: An integer
*/
public int query(int a) {
// write your code here
return size[find(a)];
}
}
示例三 - 联通块总数
public class ConnectingGraph3 {
/**
* @param a: An integer
* @param b: An integer
* @return: nothing
*/
int count;
int[] father;
public ConnectingGraph3(int n) {
father = new int[n + 1];
count = n;
for (int i = 1; i <= n; i++) {
father[i] = i;
}
}
public void connect(int a, int b) {
// write your code here
int root_a = find(a);
int root_b = find(b);
if (root_a != root_b) {
count--;
father[root_a] = root_b;
}
}
/**
* @return: An integer
*/
public int query() {
// write your code here
return count;
}
private int find(int x) {
if (father[x] == x) {
return father[x];
}
return father[x] = find(father[x]);
}
}