并查集的测试不好搞,这里以蓝桥oj判断来实行
蓝桥幼儿园
并查的步骤:
1.初始化数组
p=[ i for i in range(n+1)]
一旦自作主张:[i for i in range(1,n+1)] 使其没有0,会使原数与下表对不上
2.编写查找函数
#这是优化版本
def find(x):
if p[x]!=x:
p[x]=find(p[x])
return p[x]
3.编写合并函数
def union(x,y):
if find(x)!= find(y):
p[find(x)]= find(y)
配合测试
for i in range(m):
op,x,y=map(int,input().split())
if op==1:
union(x,y)
elif op==2:
if find(x)==find(y):
print("YES")
else:
print("NO")
总代码
n,m=map(int,input().split())
p=[ i for i in range(n+1)] #1,2,3,4....n
def find(x):
if p[x]!=x:
p[x]=find(p[x])
return p[x]
def union(x,y):
if find(x)!= find(y):
p[find(x)]= find(y)
for i in range(m):
op,x,y=map(int,input().split())
if op==1:
union(x,y)
elif op==2:
if find(x)==find(y):
print("YES")
else:
print("NO")
理解下这个过程:
n,m=map(int,input().split())
s=[i for i in range(n+1)]
def find(x):
if x!=s[x]:
s[x]=find(s[x])
return s[x] #x与s[x]相等了
def union(x,y):
if find(x)!=find(y):
s[find(x)]=find(y) #union(4,3) 4的index可以让3 占有,不就是3是4的大哥吗?
union(4,3) #4认3做帮主
print(s)
union(3,2) #3认2
print(s)
union(2,1) #2认1
print(s)
union(4,5) #4认5
print(s)
这里我们分别合并了(4,3)、(3,2)、(2,1)、(4,5)
前三项:
[0, 1, 2, 3, 3, 5, 6, 7, 8, 9]
[0, 1, 2, 2, 3, 5, 6, 7, 8, 9]
[0, 1, 1, 2, 3, 5, 6, 7, 8, 9]
的意义主要以 s[find(x)]=find(y) 为主
x认了y做大哥,x的位置可以显示y
而最后一项:
[0, 5, 1, 1, 1, 5, 6, 7, 8, 9]
从程序角度分析:
union (4,5):
index=[0,1,2,3,4,5,6]
s= [0,1,1,2,3,5,6]
union(4,5)
find(4)=[
s[4]=find(s[4]也就是3)即find[3]
find(3)= s[e]=find(2)
find(2)= find(s[2])=
find(1)=1 #满足条件
#则返回: find(1 到 4)都返回了1
]
这个过程更新了列表
[0, 1, 1, 1, 1, 5, 6, 7, 8, 9]
find(5)=5
最后1认5做了大哥