0
点赞
收藏
分享

微信扫一扫

关于最短路的算法

蒸熟的土豆 2022-04-01 阅读 92

1.Dijkstra算法(单源最短路径)

例题:蓝桥王国

3 3 
1 2 1
1 3 5
2 3 2

0 1 3

1.用到bfs和优先队列,每次从未标记的点中,选择距离出发点最近的节点,标记。

2.计算队列中弹出节点a的临近节点b,如果节点b从经过a这条路走的距离小于原来的,更新b的距离,把b也加入队列中

3.如果弹出的节点是打过标记的节点,直接跳过,因为此节点到起点的最短路径已找到。

from queue import *
n,m=map(int,input().split())
vis=[0 for i in range(n+1)]
d=[float("inf") for i in range(n+1)]
edge=[[]for i in range(m+1)]
for i in range(m):
    u,v,w=map(int,input().split())
    edge[u].append([w,v])
def dijkstra():
    p=PriorityQueue()
    p.put((0,1))
    d[1]=0
    while not p.empty():
        q=p.get()
        node,dis=q[1],q[0]
        if vis[node]==1:
            continue
        vis[node]=1
        for w,v in edge[node]:
            if d[v]>dis+w:
                 d[v]=dis+w
                 p.put((d[v],v))
    for i in range(1,n+1):
        if d[i]==float("inf"):
            print(-1)
        else:
            print(d[i],end=' ')
dijkstra()

2.Floyd 算法   多源最短路径

蓝桥公园

N=405
dp=[[float('inf') for i in range(N)]for j in range(N)]
def floyd():
     for k in range(1,n+1):
          for i in range(1,n+1):
               for j in range(1,n+1):
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])
n,m,p=map(int,input().split())
for j in range(m):
     i,j,e=map(int,input().split())
     dp[i][j]=dp[j][i]=e
floyd()
for i in range(p):
     s,t=map(int,input().split())
     if dp[s][t]==float('inf'):
          print(-1)
     if s==t:
          print(0)
     else:
          print(dp[s][t])

 3.SPFA算法(单源最短路径,边权为负)

  1. 起点 s 入队,计算它所有邻居到 s 的最短距离(当前最短距离,不是全局最短距离。下文中,把计算一个结点到起点 s 的最短路径简称为更新状态。最后的“状态”就是 SPFA 的计算结果)。把 s 出队,状态有更新的邻居入队,没更新的不入队。也就是说,队列中都是状态有变化的结点,只有这些结点才影响最短路径的计算。
  2. 现在队列的头部是 s 的一个邻居 u。弹出 u,更新它所有邻居的状态,把其中有状态变化的邻居入队列。
  3. 弹出 u 之后,在后面的计算中,u 可能会再次更新状态(后面 u 可能借道别的结点去 s,路更近),u 需要重新入队列。这一点很容易做到:处理一个新的结点 v 时,它的邻居可能就是以前处理过的 u,如果 u 的状态变化了,把 u 重新加入队列就行了。
  4. 继续以上过程,直到队列空。这也意味着,所有结点的状态都不再更新。最后的状态就是到起点 s 的最短路径。

from queue import *
n,m=map(int,input().split())
vis=[0 for i in range(n+1)]
d=[float("inf") for i in range(n+1)]
edge=[[]for i in range(m+1)]
for i in range(m):
    u,v,w=map(int,input().split())
    edge[u].append([w,v])
def spfa():
    q=Queue()
    q.put(1)
    d[1]=0
    vis[1]=1
    while not q.empty():
         p=q.get()
         vis[p]=0
         for dist,son in edge[p]:
              if d[son]>d[p]+dist:
                   d[son]=d[p]+dist
              if vis[son]==0:
                   q.put(son)
                   vis[son]=1
spfa()
for i in range(1,n+1):
     if d[i]==float('inf'):
          print(-1,end=' ')
     else:
          print(d[i],end=' ')

举报

相关推荐

0 条评论