UnionFind:快查连通图
并查集UnionFind又叫Disjoint Sets。它的作用是快速更新和查询节点的连通性。
数组简单实现
简单的并查集实现如下:用数组表示祖节点。
主要功能:
find(p):O(N)找到p所在连通图的根 实现:不断向父节点查找union(p, q):(N)把p和q连通 实现:把含有p的根接到含有q的根上connected(p, q):O(N)判断p和q是否连通 实现:判断含有p和q的数是否有一样的根节点self.count:O(1)得到连通图的个数
class UF:
def __init__(self, n):
self.parent = [x for x in range(n)]
self.count = n
def find(self, p):
while self.parent[p]!=p:
p = self.parent[p]
return p
def union(self, p, q):
rootp, rootq = self.find(p), self.find(q)
if rootp==rootq: return
self.parent[rootp] = rootq
self.count -= 1
def connected(self, p, q):
return self.find(p)==self.find(q)路径压缩 / 小树接大树
在这里可以有一些优化:在union过程中加入平衡考虑(小树接大树),以及在find过程中顺便加入路径压缩,可以让查找和union更快。具体可以参考此文。这样一来,find,union,connected的时间复杂度都降到了O(logN)。
带权重的UnionFind
目前的UnionFind是一个无向的多叉树。有时候要求不仅能求连通性,而且要计算节点之间的连接的权重。这个时候就需要一个带权重的UnionFind,成为一个无环有向图。
下面的参考代码在“查询“操作的“路径压缩“优化中维护权值变化。
例题:快速除法
Last updated
Was this helpful?