本文首发在我的个人博客:https://jlice.top/p/7ta3x/。欢迎大家前去参观,么么哒~
引言
有若干节点,并将其中一些节点对进行连接,要判断任意两个节点是否连通(有路径到达,而不要求直接连接),连通后就不会断开连通关系,此时就可以使用并查集。并查集擅长动态维护许多具有传递性的关系,能在无向图中维护节点之间的连通性。
要判断两个节点是否连通,可以把连通的节点加入到各自的集合里,也就是,同一个集合里的节点都是连通的,不同集合里的节点是不连通的。
如图,节点a、b、c、d属于同一个集合,它们之间是连通的;节点x、y、z属于同一个集合,它们之间也是连通的。但是,不同集合里的节点,如b和x,是不连通的。
可以发现,每个集合构成了树形的结构,同一个集合里的节点,它们的根节点是相同的。要判断两个节点是否连通,只需要判断它们的根节点是否一致即可。
并查集的API定义:
class UF {
public:
// 查找节点的根节点
int find(int x) {
};
// 连接节点p和q
void join(int x, int y) {
};
// 判断两个节点是否连通
bool isConnected(int x, int y) {
return find(x) == find(y);
};
};
实现
并查集的存储结构可以使用数组或链表,一般采用数组作为实现的方式。数组记录元素的父节点。例如,A[i] = j,表示节点i的父节点是节点j。
初始时,每个节点各自作为一个集合,也就是节点的父节点是自身。
private:
vector<int> parent;
public:
UF(int n) {
for (int i = 0; i < n; i++) {
parent.push_back(i);