并查集常用来解决连通性问题。
即需要判断两个元素是否在同一个集合里的时候,我们就要想到用并查集。
并查集主要有两个功能:
- 将两个元素添加到一个集合中。
- 判断两个元素在不在同一个集合
并查集代码模板:
class UnionFind:
def __init__(self, n):
self.n = n
self.father = [i for i in range(n)] # Python中的列表用作并查集的数组
def init(self):
# 并查集初始化,每个节点的父节点指向自己
self.father = [i for i in range(self.n)]
def find(self, u):
# 并查集里寻根的过程,路径压缩
if u != self.father[u]:
self.father[u] = self.find(self.father[u]) # 递归地进行路径压缩
return self.father[u]
def is_same(self, u, v):
# 判断 u 和 v 是否找到同一个根
return self.find(u) == self.find(v)
def join(self, u, v):
# 将 v 和 u 合并到同一个集合中
root_u = self.find(u)
root_v = self.find(v)
if root_u == root_v:
return # 如果根相同,说明已经在同一个集合,直接返回
self.father[root_v] = root_u # 否则,将 v 的根的父节点设置为 u 的根
主要就是集合问题,两个节点在不在一个集合,也可以将两个节点添加到一个集合中。
class UnionFind:
def __init__(self, n):
self.n = n
self.father = [i for i in range(n + 1)] # 按照节点大小定义数组大小,Python索引从0开始
def init(self):
# 并查集初始化,每个节点的父节点指向自己
self.father = [i for i in range(self.n + 1)]
def find(self, u):
# 并查集里寻根的过程,路径压缩
if u != self.father[u]:
self.father[u] = self.find(self.father[u]) # 递归地进行路径压缩
return self.father[u]
def is_same(self, u, v):
# 判断 u 和 v 是否找到同一个根
return self.find(u) == self.find(v)
def join(self, u, v):
# 将 v 和 u 合并到同一个集合中
root_u = self.find(u)
root_v = self.find(v)
if root_u == root_v:
return # 如果已经在同一个集合,则直接返回
self.father[root_v] = root_u # 否则,将一个节点的根的父节点设置为另一个节点的根
def main():
n, m = map(int, input().split())
union_find = UnionFind(n)
union_find.init()
while m:
s, t = map(int, input().split())
union_find.join(s, t)
m -= 1
source, destination = map(int, input().split())
if union_find.is_same(source, destination):
print(1)
else:
print(0)
if __name__ == "__main__":
main()