文章目录
总述
- 合并(Union): 将两个集合合并成一个集合。
- 查询(Find): 查找某个元素所属的集合。
合并过程
s = [i for i in range(N+1)] # 列表s[i] 表示i 节点的父节点,开始的时候,全部指向自己
def union(x,y):
r1 = find(x)
r2 = find(y)
if r1 != r2:
s[r1] = s[r2]
查找过程
def find(x): # 返回 x 的根节点
if x != s[x]:
s[x] = find(s[x])
return s[x]
算法实战
实战1
from collections import defaultdict
n = int(input())
p = [i for i in range(n + 1)] # p[i] 表示 节点 i 的父节点
tree = defaultdict(list) # 输入键,当键不存在就生成键:列表
used = [0] * (n + 1) # 用来记录是否访问过
ans = [0] * n # 用来反复记录路径
def find(x): # 并查集的查找函数,返回x 节点的根
if x != p[x]:
p[x] = find(p[x])
return p[x]
def dfs(pos, idx):
ans[idx] = pos
if pos == end:
res = sorted(ans[:idx + 1]) # 排序
print(' '.join(map(str, res))) # 输出,间隔空格输出
return
for d in tree[pos]: # 逐一访问节点的邻接节点
if not used[d]: # 由于是无向图,并且加上深度搜索,所以要记录一个节点是否已经访问过
used[d] = 1
dfs(d, idx + 1)
for _ in range(n):
u, v = map(int, input().split())
tu, tv = find(u), find(v)
if tu == tv:
start, end = u, v
break # 所以是不必加载全部的边的关系的,因为当两个输入的节点的根相同的时候,就说明已经包含环了
else:
p[tv] = tu
tree[u].append(v)
tree[v].append(u) # 无向图
used[start] = 1
dfs(start, 0)
代码分析