带权图的最短路径

import heapq
def heappath(edges):
    dist = [float('inf')] * len(edges)
    dist[0] = 0
    pre=[-1 for _ in range(len(edges))] #路径中的前一顶点
    q = []
    heapq.heappush(q, [0, 0])#小堆q,q[0]最短路径值,q[1]到达顶点
    while q:
        _, u = heapq.heappop(q)
        for i in edges[u]:#Vmin做为中间顶点,调整集合V-U中的顶点的最短路径
            if dist[i[0]] > dist[u] + i[1]:
                dist[i[0]] = dist[u] + i[1]
                pre[i[0]] = u
                heapq.heappush(q, [dist[u] + i[1], i[0]])#堆顶的顶点i[0](Vmin)是放入U的已求出最短路径
    return dist,pre
edges = (((1, 50), (2, 10), (4,45)),
         ((2, 15), (4, 5)),
         ((0, 20), (3, 15)),
         ((1, 20), (4, 35)),
         ((3, 30),),
         ((3, 3),),)#((3, 30),)顶点v4,可到达顶点v3,路径值为30
#([0, 45, 10, 25, 45, inf], [-1, 3, 0, 2, 0, -1])
def dijkstra(e):
    n = len(e)
    dist=[[0,-1] for _ in range(n)]
    a=[[float('inf') for _ in range(n)] for _ in range(n)]#graph.arcs
    for i in range(n):
        a[i][i] = 0
    for i in range(n):
        for j in range(len(e[i])):
            a[i][e[i][j][0]] = e[i][j][1]    
    dist[0][0]=0#length
    dist[0][1]=0#path
    a[0][0]=1#表示顶点v0在集合U中    
    for i in range(1,n):#初始化集合V-U中顶点的距离值
        dist[i][0] = a[0][i]
        if dist[i][0] != float('inf'):
            dist[i][1] = 0
        else:
            dist[i][1] = -1
    for i in range(1,n):
        minw = float('inf')
        min = 0
        for j in range(1,n):#在V-U中选出距离最小顶点
            if a[j][j] == 0 and dist[j][0] < minw:
                minw = dist[j][0]
                min = j
        if 0==min:break #从v0没有路径可以通往集合V-U中的顶点
        a[min][min] = 1
        for j in range(1,n):#调整集合V-U中的顶点的最短路径
            if 1 == a[j][j]:continue
            if dist[j][0]>dist[min][0]+a[min][j]:
                dist[j][0] = dist[min][0]+a[min][j]
                dist[j][1] = min
    print(dist)
#[[0, 0], [45, 3], [10, 0], [25, 2], [45, 0], [inf, -1]]    
def floyd(e):
    n = len(e)
    a=[[float('inf') for _ in range(n)] for _ in range(n)]
    nextvex=[[-1 for _ in range(n)] for _ in range(n)]
    for i in range(n):
        a[i][i] = 0
        nextvex[i][i] = i
    for i in range(n):
        for j in range(len(e[i])):
            a[i][e[i][j][0]] = e[i][j][1]
            nextvex[i][e[i][j][0]] = e[i][j][0]

    for k in range(n):#依次加入v0~v(n-1)的顶点k
        for i in range(n):
            for j in range(n):
                if float('inf') == a[i][k] or float('inf') == a[k][j]:continue
                if a[i][j]>(a[i][k]+a[k][j]):
                    a[i][j] = a[i][k]+a[k][j]
                    nextvex[i][j] = nextvex[i][k]
    print(a)
    print(nextvex)
'''
[[0, 50, 10, inf, 45, inf],
 [inf, 0, 15, inf, 5, inf],
 [20, inf, 0, 15, inf, inf],
 [inf, 20, inf, 0, 35, inf],
 [inf, inf, inf, 30, 0, inf],
 [inf, inf, inf, 3, inf, 0]]
[[0, 1, 2, -1, 4, -1],
 [-1, 1, 2, -1, 4, -1],
 [0, -1, 2, 3, -1, -1],
 [-1, 1, -1, 3, 4, -1],
 [-1, -1, -1, 3, 4, -1],
 [-1, -1, -1, 3, -1, 5]]
'''    

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值