并查集的基本操作

并查集的基本操作


一、初始化

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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值