目录
一、并查集操作
原理可以参考这位up主:并查集原理精讲_哔哩哔哩_bilibili
1.初始化
fa = [] # i的父亲是fa[i]
for i in range(N):
fa.append(i)
代码简化:
fa = list(range(N))
2.查找(路径压缩)
def find(i): # 找i的祖先
if i == fa[i]: # 到达祖先位置
return i # 返回祖先
fa[i] = find(fa[i]) # 路径压缩:使i指向祖先而不是父亲
return fa[i] # 返回父亲
代码简化:
def find(i):
if i != fa[i]:
fa[i] = find(fa[i])
return fa[i]
时间复杂度:O(log(n))
路径压缩 与 按秩合并 在实际运行时,运行效率其实差不多,所以用路径压缩法即可
3.合并
def union(i, j): # 数组--> 树
i_fa = find(i) # 找到i的祖先
j_fa = find(j) # 找到j的祖先
fa[i_fa] = j_fa # i的祖先箭头指向j的祖先
代码简化:
fa[find(i)] = find(j)
二、AcWing 1249. 亲戚(每日一题)
1.题目描述
2.代码实现
本题数据量较大,要使用快读,否则会TLE
from sys import *
N, M = map(int, input().split())
fa = list(range(N + 1)) # 下标当从1开始
def find(i):
if i != fa[i]:
fa[i] = find(fa[i])
return fa[i]
for _ in range(M):
a, b = map(int, stdin.readline().split()) # 快读
fa[find(a)] = find(b)
for _ in range(int(input())):
c, d = map(int, stdin.readline().split()) # 快读
# 如果c和d有同一个祖先,那么c和d就是亲戚
print("Yes" if find(c) == find(d) else "No")
如有不足或不解之处欢迎留言指正哈。
如有帮助可以点赞收藏嘛,感谢~