KY49 Jungle Roads

KY49 Jungle Roads

# Kruskal算法
import collections, heapq
DirectedEdge = collections.namedtuple('DirectedEdge',['cost','src','dst'])
def getRoot(RootsDict, child):
    if child not in RootsDict:
        RootsDict[child] = child
        return child
    elif RootsDict[child] == child:
        return child
    else:
        root = getRoot(RootsDict, RootsDict[child])
        RootsDict[child] = root
        return root
def main(N):
    EdgesDict, CostDict = dict(), dict()
    for i in range(N-1):
        info = input().strip().split()
        src, roadNUM = info[0], eval(info[1])
        for j in range(roadNUM):
            dst, cost = info[2 + 2 * j], eval(info[3 + 2 * j])
            if src == dst:
                continue
            if cost < CostDict.get((src, dst), 10**12):  # 判断是否为自回路,以及边是否重复,但是花费不同
                edge1, edge2 = DirectedEdge(cost, src, dst), DirectedEdge(cost, dst, src)
                EdgesDict[src] = EdgesDict.get(src, list()) + [edge1]
                EdgesDict[dst] = EdgesDict.get(dst, list()) + [edge2]
                CostDict[(src, dst)], CostDict[(dst, src)] = cost, cost
    MST_cost, MST_Edge_NUM, VertexNUM, Edges = 0, 0, len(EdgesDict), list()
    RootsDict, HeigetsDict = dict(), dict()
    for value in EdgesDict.values():
        Edges.extend(value)
    heapq.heapify(Edges)
    while MST_Edge_NUM < VertexNUM - 1:
        edge = heapq.heappop(Edges)
        src, dst, cost = edge.src, edge.dst, edge.cost
        if src == dst:
            continue
        src_root, dst_root = getRoot(RootsDict, src), getRoot(RootsDict, dst)
        if src_root == dst_root:
            continue
        src_root_height, dst_root_height = HeigetsDict.get(src_root, 1), HeigetsDict.get(dst_root, 1)
        if src_root_height > dst_root_height:
            RootsDict[dst_root] = src_root
        elif src_root_height < dst_root_height:
            RootsDict[src_root] = dst_root
        elif src_root_height == dst_root_height:
            RootsDict[dst_root] = src_root
            HeigetsDict[src_root] = 1 + src_root_height
        MST_Edge_NUM, MST_cost = MST_Edge_NUM + 1, MST_cost + cost
    print(MST_cost)
if __name__=='__main__':
    try:
        while True:
            N = int(input())
            if N == 0:
                break
            else:
                main(N)
    except:
        pass
# Prim算法求解
import collections, heapq
DirectedEdge = collections.namedtuple('DirectedEdge',['cost','src','dst'])

def main(N):
    EdgesDict, CostDict = dict(), dict()
    for i in range(N-1):
        info = input().strip().split()
        src, roadNUM = info[0], eval(info[1])
        for j in range(roadNUM):
            dst, cost = info[2 + 2 * j], eval(info[3 + 2 * j])
            if src == dst:
                continue
            if cost < CostDict.get((src, dst), 10000):  # 判断是否为自回路,以及边是否重复,但是花费不同
                edge1, edge2 = DirectedEdge(cost, src, dst), DirectedEdge(cost, dst, src)
                EdgesDict[src] = EdgesDict.get(src, list()) + [edge1]
                EdgesDict[dst] = EdgesDict.get(dst, list()) + [edge2]
                CostDict[(src, dst)], CostDict[(dst, src)] = cost, cost
    MST_cost, MST_Edge_NUM, VertexNUM = 0, 0, len(EdgesDict)
    MST_Vertex, adjEdges = EdgesDict.popitem()
    MST_Vertex = {MST_Vertex}
    heapq.heapify(adjEdges)
    adjEdges = adjEdges[:]
    while MST_Edge_NUM < VertexNUM - 1:
        edge = heapq.heappop(adjEdges)
        if edge.dst in MST_Vertex:
            continue
        else:
            MST_Vertex.add(edge.dst)
            for item in EdgesDict[edge.dst]:
                heapq.heappush(adjEdges, item)
            MST_cost, MST_Edge_NUM = MST_cost + edge.cost, MST_Edge_NUM + 1
    print(MST_cost)

if __name__=='__main__':
    try:
        while True:
            N = int(input())
            if N == 0:
                break
            else:
                main(N)
    except:
        pass
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值