并查集理论基础
并查集主要有两个功能:
- 将两个元素添加到一个集合中。
- 判断两个元素在不在同一个集合
class UnionFind: def __init__(self, n): """初始化并查集""" self.n = n self.father = list(range(n)) # 每个节点自己是根 self.rank = [1] * n # 每棵树初始高度为1 def find(self, u): """查找根节点,同时做路径压缩""" if self.father[u] != 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): """按秩合并 u 和 v 所在集合""" u_root = self.find(u) v_root = self.find(v) if u_root == v_root: return # 已经在同一个集合 # 按秩合并:小树挂到大树下面 if self.rank[u_root] < self.rank[v_root]: self.father[u_root] = v_root elif self.rank[u_root] > self.rank[v_root]: self.father[v_root] = u_root else: self.father[u_root] = v_root self.rank[v_root] += 1
1.寻找存在的路径

主函数逻辑
main
函数是程序的执行入口,它负责处理输入、调用并查集的方法,并输出结果。它的步骤是:
读取输入 :一次性读取所有输入数据,包括元素的总数
n
、操作的次数m
,以及所有的合并和查询数据。初始化并查集 :创建一个
UnionFind(n)
的实例,准备好处理n
个元素。执行合并操作 :通过一个循环,读取
m
对元素,并对每一对元素调用uf.union()
方法,将它们所在的集合合并。执行查询 :读取最后需要查询的一对元素
source
和destination
。输出结果 :调用
uf.is_same()
方法来判断source
和destination
是否属于同一个集合,然后根据结果输出1
或0
。
class UnionFind:
#每个人的根都指向自己
def init(self, size):
self.parent = list(range(size+1))
def find(self, u):
if self.parent[u] != u:
self.parent[u] = self.find(self.parent[u]) # 路径压缩
return self.parent[u]
def union(self, u, v):
root_u = self.find(u)
root_v = self.find(v)
if root_u != root_v:
self.parent[root_v] = root_u
#检查两个元素 u 和 v 是否属于同一个集合(也就是它们是否"连通")
def is_same(self, u, v):
return self.find(u) == self.find(v)
def main():
#sys.stdin.read 这个方法有点不一样。它是从标准输入流中一次性读取所有的输入
import sys
input = sys.stdin.read
data = input().split()
index = 0
n = int(data[index])
index += 1
m = int(data[index])
uf = UnionFind(n)
index += 1
for _ in range(m):
s = int(data[index])
index += 1
t = int(data[index])
index += 1
uf.union(s, t)
source = int(data[index])
index += 1
destination = int(data[index])
if uf.is_same(source, destination):
print(1)
else:
print(-1)
if name == "main":
main()
今天就到这里了有点难!