Python算法模版:图论中的最短路径算法

        这一篇主要记录在图论中求最短路径的几个算法的python模版,用于本人日后忘记的话复习用,对于有问题的地方,大家也可以在评论区指导一下。

单源最短路径算法:Dijkstra

        对于Dijkstra来说,他的所有边必须是正权边,也就是说他无法解决边权存在负数的情况,时间复杂度为nlogm

        首先对于题目所给的数据进行处理,一般我们将其放入矩阵,将边和边的权值放入列表list_g中去

n,m=map(int,input().split())
inf=1e6
list_g = [[inf] * (n+1) for i in range(n+1)]
for _ in m:
    u,v,w=map(int,input().split())
    list_g[u][v] = list_g[v][u]=min(list_g[u][v],w)

        然后开始写Dijkstra算法,我们令k为起点

def dsk(list_g,n,k):
    dist, s = [inf] * (n+1), [False] * (n+1)
    dist[k] = 0
    for i in range(n):
        x = -1
        #找最小值
        for j in range(1,n+1):
            if not s[j] and (x == -1 or dist[j] < dist[x]):
                x = j
        #标记最小值
        s[x] = True
        #遍历图
        for j in range(1,n+1):
            dist[j] = min(dist[j], dist[x] + list_g[x][j])
    

        还有一种模版利用分支限界法里面优先队列的方式来实现Dijkstra,首先要先导入Python里自带的优先队列

from queue import PriorityQueue

def fun(s):
    d=[inf] * (n+1)
    vis = [0] * (n+1)
    q = PriorityQueue()

    d[s]=0
    q.put((d[s],s))
    while not q.empty():
        dis , u = q.get()
        if vis[u]:continue
        vis[u]=1
        for i in range(1,n+1):
            if d[v] > d[u] + list_g[u][v]
                d[v] = d[u] + list_g[u][v]
                q.put((d[v],v))

单源最短路径算法:Bellman-Ford 

         Bellman-Ford算法可以处理存在负权值的情况,时间复杂度为nm,数据处理如下

n, m = map(int, input().split())
s = []
for i in range(m):
    u, v, w = map(int, input().split())
    s.append((u, v, w))
    s.append((v, u, w))

        核心思想就是遍历n-1边,如果还能更新,也就是说存在负权回路,一般题目没有,除非强调,判断自己也可以手动添加

inf = 1e9
d = [inf] * (n + 1)
d[1] = 0

for _ in range(n - 1):
    for u, v, w in s:
        if d[v] > d[u] + w:
            d[v] = d[u] + w

多源最短路径算法:Floyd

        Floyd的时间复杂度为n^3,碰到大数量级别的例子直接是超时的,也不建议使用,最开始用矩阵来存储数据

INF = 1e6

n, m, q = map(int, input().split())
dis = [[INF] * (n + 1) for _ in range(n + 1)]

for i in range(1, n + 1):
    dis[i][i] = 0

for _ in range(m):
    u, v, w = map(int, input().split())
    dis[u][v] = dis[v][u] = min(dis[u][v], w)

        开始写框架,更新最小路径

for k in range(1, n + 1):
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j])

多源最短路径其他算法

        对于其他算法,可以直接n次Bellman-Ford,时间复杂度乘以n,为n^2m

        亦可以n次Dijkstra,时间复杂度为n^2logm

        同时也可以采用JohnSon算法,就是将Bellman-Ford和Dijkstra结合起来,同时也可以有负权的存在,时间复杂度为n^2logm,对于以上的三种算法模版我就不在这里写了,大家感兴趣的话可以自己搜搜看,或者写出来

总结

        这次的算法模版就分享到这里了,如果对你有帮助就请收藏起来吧,如果有文体业请多多指教。

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值