文章目录
任何一种算法都是为解决某个问题而生的,
union-find
是用于解决
动态连通性问题的一种算法。
动态连通性
考虑有一列整数对,一对整数p
和q
可以被理解为p和q是相连的。我们假设相连是一种等价关系,它具有:
(1)
自反性:p
和p
是相连的。
(2)
对称性:如果p
和q
是相连的,那么q
和p
也是相连的。
(3)
传递性:如果p
和q
相连,且q
和r
相连,那么p
和r
也是相连的。
当且仅当两个对象相连时它们就属于同一个等价类,因此可以把对象分为多个等价类。
我们将对象称为触点,将整数对称为连接,将等价类称为连通分量或分量。
每个分量包含多个触点,且有一个标识符。
API
为了简单说明问题,我们的触点都是从0开始连续的非负整数。
void Union(int p, int q); // 连接p和q
int Find(int p); // p所在分量的标识符
bool Connected(int p, int q); // p和q是否连接
size_t Count(); // 连通分量的数量
如果两个触点在不同的分量中,Union
操作会把两个分量合并;Find
操作会返回给定触点所在的连通分量的标识符;Connected
操作能够判断两个触点是否属于同一个分量;Count
操作返回所有连通分量的个数。
如一开始有N
个分量,将连个分量归并的Union
操作都会使分量总数减1。
如此一来,就把解决动态连通性问题转化为了实现上述API。我们需要提供一种数据结构表示已知的连接,并基于此高效地实现这些API。
union-find声明
union_find.h
#ifndef UNION_FIND
#define UNION_FIND