UnionFind用于解决图的连通性问题,不需要给出具体路径的情况,可用来计算连通分支数
参考链接:
- https://blog.csdn.net/dm_vincent/article/details/7655764
- https://www.cnblogs.com/SeaSky0606/p/4752941.html
这两篇博客对于问题讲的非常好,本文只给出Python的实现代码,以供参考
class Quick_Find:
def __init__(self,N):
self.count = N
self.ids = [i for i in range(self.count)]
def connect(self,p,q):
return self.find[p] == self.find(q)
def find(self,p):
return self.ids[p]
def union(self,p,q):
pId = self.find(p)
qId = self.find(q)
if pId == qId:
return
for i in range(len(self.ids)):
if self.ids[i] == pId:
self.ids[i] = qId
self.count-=1
def getcount(self):
return self.count
class Quick_Union:
def __init__(self,N):
self.count = N
self.ids = [i for i in range(N)]
def connect(self,p,q):
return self.find(p) == self.find(q)
def find(self,p):
while self.ids[p] != p: # 循环,直到找到根节点
p = self.ids[p]
return p
def union(self,p,q):
pID = self.find(p)
qID = self.find(q)
if pID == qID:
return
self.ids[pID] = qID
self.count -= 1
def getcount(self):
return self.count
class Weighted_Union_Find:
def __init__(self,N):
self.count = N
self.ids = [i for i in range(N)]
self.size = [1 for i in range(N)] # 加权
def connect(self,p,q):
return self.find(p) == self.find(q)
def find(self,p):
while self.ids[p] != p:
p = self.ids[p]
return p
def union(self,p,q):
pID = self.find(p)
qID = self.find(q)
if pID == qID:
return
if self.size[pID] < self.size[qID]: # 小的树并到大的树下
self.ids[pID] = qID
self.size[qID] += self.size[pID]
else:
self.ids[qID] = pID
self.size[pID] += self.size[qID]
self.count-=1
def getcount(self):
return self.count
if __name__ == '__main__':
N,M = list(map(int,input().split())) # N为节点数目 M为输入关系系的数目
# uf = Quick_Find(N)
# uf = Quick_Union(N)
uf = Weighted_Union_Find(N)
for i in range(M):
p,q = list(map(int,input().split())) # p、q建立关系
if not uf.connect(p,q): # 若还未连接
uf.union(p,q)
print(uf.getcount())
输入测试:
8 5
2 3
1 0
0 4
5 7
6 2
result:3