并查集理论基础:
107.寻找存在的路径:
思路
首先分析题目,给定的是无向图,要求的是判断从节点source到destination是否存在路径。
如果存在路径,说明source到destination是通过多条路径连在一起,也就是source和destination在一个强连通分量的图中,即这两个在一个集合中。
而只要求判断两个元素是否在一个集合中,且是无向图,使用并查集进行判断。
- 首先按照输入的边构造并查集
- 最后查找source和destination是否存在同一个集合中(即根相同)
并查集的相关代码
class UnionFind():
def __init__(self, size):
self.parent = [x for x in range(size + 1)] # 节点编号从1开始
def find(self, u):
if self.parent[u] != u:
self.parent[u] = self.find(self.parent[u]) # 路径压缩
return self.parent[u]
def is_same(self, u, v):
return self.find(u) == self.find(v)
# 将v→u加入并查集中
def join(self, u, v):
root_u = self.find(u)
root_v = self.find(v)
if root_v != root_u:
self.parent[root_v] = root_u
本题中使用并查集
def main():
n, m = map(int, input().split())
uf = UnionFind(n)
for _ in range(m):
s, t = map(int, input().split())
uf.join(s, t) # 因为是无向图,而且只求是否存在路径,因此正反都可以
source, dest = map(int, input().split())
if uf.is_same(source, dest): # 在一个集合中
print(1)
else:
print(0)
if __name__ == '__main__':
main()
学习收获:
并查集用于判断两个元素是否在同一个集合中。要求是要能分析出题目要使用并查集进行判断。
并查集通过单数组来保存,即二叉树的逆,从叶节点向上寻根,parent[x] = y。
并查集要注意的:初始化:parent[x] = x; 寻根:使用路径压缩,将节点都挂到根节点下;是否存在同一个节点中:寻的根是否相同;加入路径:先寻两个节点的根,不相同(即不存在路径)的话,parent[root_v] = root_u