作用:检查图上面是否存在环

先将连通的节点加入集合,如果再选中的边的两个顶点已经在集合里了,说明出现环
合并算法:
1.一维数组
全是 -1 初始化表示独立
parent[1] = 0 说明1的父节点是0
parent[2]= 0 说明2的父节点也是0
012三个节点就可以连接起来
2.如何连接两棵树(并)
为了不形成断层和路径过长
分别找到父节点,然后连接(查)
结论:构造出parent数组之后,如果两个节点根节点一样,则说明有环

寻找x, y的根节点 x_root, y_root然后合并
分为两个函数find_root(), union() 找根节点和合并()查和并
n = len(verticices)parent = [-1] * n## 找到根节点(-1)为止def find_root(x, parent):x_root = xwhile parent[x_root] != -1:x_root = parent[x_root]return x_root## return: True/Falsedef union(x, y, parent):x_root = find_root(x)y_root = find_root(y)if x_root == y_root:return Falseparent[x_root] = y_rootreturn True
union算法问题:如果图链特别长,查找parent数组复杂度将会变成o(logn)?复杂度
引进新变量 Rank
n = len(verticices)parent = [-1] * nrank = [0] * n## 找到根节点(-1)为止def find_root(x, parent):x_root = xwhile parent[x_root] != -1:x_root = parent[x_root]return x_root## return: True/Falsedef union(x, y, parent, rank):x_root = find_root(x)y_root = find_root(y)if x_root == y_root:return False## 路径压缩算法if rank[x_root] > rank[y_root]:parent[y_root] = x_rootelif rank[y_root] > rank[x_root]:parent[x_root] = y_rootelse:parent[y_root] = x_rootrank[x_root] += 1return True
总结: parent[], rank []
find_root()
union() + 路径压缩
模板
class UnionFind:def __init__(self):"""记录每个节点的父节点"""self.father = {}def find(self,x):"""查找根节点路径压缩"""root = xwhile self.father[root] != None:root = self.father[root]# 路径压缩while x != root:original_father = self.father[x]self.father[x] = rootx = original_fatherreturn rootdef merge(self,x,y,val):"""合并两个节点"""root_x,root_y = self.find(x),self.find(y)if root_x != root_y:self.father[root_x] = root_ydef is_connected(self,x,y):"""判断两节点是否相连"""return self.find(x) == self.find(y)def add(self,x):"""添加新节点"""if x not in self.father:self.father[x] = None作者:MiloMusiala链接:https://leetcode-cn.com/problems/evaluate-division/solution/pythonbing-cha-ji-fu-mo-ban-by-milomusia-kfsu/来源:力扣(LeetCode)著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
