并查集的基本操作
一、初始化
parent=dict()
rank=dict()
def initSet(x):
parent[x]=x
rank[x]=0
需要一个parent字典代表其根,rank代表他的深度
二、查找
def findParent(x):
if parent[x]==x:
return x
else:
parent[x]=findParent(parent[x])
return parent[x]
一直向上遍历,直到为根
三、合并
def mergeSet(x,y):
x1=findParent(x)
y1=findParent(y)
if x1!=y1:
#考虑rank进行合并
if rank[x1]>rank[y1]:
parent[y1]=x1
else:
parent[x1]=y1
if rank[x1]==rank[y1]:
rank[y1]+=1
首先判断是否同根,不同根则根据深度大小来进行合并
四、举例:用并查集来判圈的Kruskal算法
from audioop import reverse
import sys
parent=dict()
rank=dict()
def initSet(x):
parent[x]=x
rank[x]=0
def findParent(x):
if parent[x]==x:
return x
else:
parent[x]=findParent(parent[x])
return parent[x]
def mergeSet(x,y):
x1=findParent(x)
y1=findParent(y)
if x1!=y1:
#考虑rank进行合并
if rank[x1]>rank[y1]:
parent[y1]=x1
else:
parent[x1]=y1
if rank[x1]==rank[y1]:
rank[y1]+=1
def kruskal(vertexs,edges):
for each in vertexs:
initSet(each)
resTree=[]
edges.sort(key=lambda x:x[2],reverse=False)
for edge in edges:
sta,des,weight=edge
if findParent(sta)!=findParent(des):
mergeSet(sta,des)
resTree.append(edge)
return resTree
def main():
n=int(input("请输入结点个数"))
vertexs=["" for _ in range(n)]
for i in range(n):
vertexs[i]=input("请输入结点%d"%(i+1))
edges=[]
for line in sys.stdin:
temp=line.split()
edges.append(temp)
result=kruskal(vertexs,edges)
print(result)
if __name__=='__main__':
main()