最短路径。

Dijkstra

1.蓝桥王国

https://www.lanqiao.cn/problems/1122/learning/?page=1&first_category_id=1&name=%E8%93%9D%E6%A1%A5%E7%8E%8B%E5%9B%BD

请添加图片描述

import heapq

def djs(s=1):
  done = [0 for i in range(N+1)]
  hp = []
  dis[s] = 0
  heapq.heappush(hp,(0,s))
  while hp:
    u = heapq.heappop(hp)[1]
    if done[u]:
      continue
    done[u] = 1
    for v,w in G[u]:
      if dis[v] > dis[u]+w:
        dis[v] = dis[u]+w
        heapq.heappush(hp,(dis[v],v))

# 请在此输入您的代码
N,M = map(int,input().split())
G = [[] for i in range(N+1)]
dis = [float('inf') for i in range(N+1)]
for i in range(M):
  u,v,w = map(int,input().split())
  G[u].append((v,w))

djs()
res = [0]
for i in range(2,N+1):
  res.append(-1 if dis[i]==float('inf') else dis[i])
print(*res)

2.\850. Dijkstra求最短路 II

https://www.acwing.com/problem/content/852/

在这里插入图片描述

import heapq
from collections import defaultdict

def dijkstra(s=1):
    done = [0 for i in range(n+1)]
    hp = []
    heapq.heappush(hp,(0,s))
    while hp:
        u = heapq.heappop(hp)[1]
        if done[u]:
            continue
        done[u] = 1
        for v,w in G[u]:
            if dist[v] > dist[u]+w:
                dist[v] = dist[u]+w
                heapq.heappush(hp,(dist[v],v))
                
n,m = map(int,input().split())
G = [[] for i in range(n+1)]
dist = [float('inf') for i in range(n+1)]
dist[1] = 0
for i in range(m):
    u,v,w = map(int,input().split())
    G[u].append((v,w))
    
dijkstra(1)
if dist[n] != float('inf'):
    print(dist[n])
else:
    print(-1)

bellman-ford

bellman - ford算法擅长解决有边数限制的最短路问题

每次询问每个点到边的下一个点有木有更短的方案

1.出差(djs/贝尔曼福特)

https://www.lanqiao.cn/problems/2194/learning/?page=1&first_category_id=1&name=%E5%87%BA%E5%B7%AE

在这里插入图片描述

djs

import heapq


n,m = map(int,input().split())
c = [0] + list(map(int,input().split()))
G = [[] for i in range(n+1)]
for i in range(m):
  u,v,w = map(int,input().split())
  G[u].append((v,w))
  G[v].append((u,w))

dis = [float('inf') for i in range(n+1)]
dis[1] = 0
hp = []
heapq.heappush(hp,(0,1))
visited = [False for i in range(n+1)]
while hp:
  u = heapq.heappop(hp)[1]
  if visited[u]:
    continue
  visited[u] = True
  for v,w in G[u]:
    if dis[v]>dis[u]+c[v]+w:
      dis[v] = dis[u]+c[v]+w
      heapq.heappush(hp,(dis[v],v))

# print(dis)
print(dis[-1]-c[-1])

贝尔曼福特

import os
import sys  

n,m = map(int,input().split())
c = [0] + list(map(int,input().split()))
G = []
for i in range(m):
  u,v,w = map(int,input().split())
  G.append((u,v,w))
  G.append((v,u,w))
dis = [float('inf') for i in range(n+1)]
dis[1] = 0
for i in range(n):
  for u,v,w in G:
    res = c[v]
    if v == n:
      res = 0
    dis[v] = min(dis[v],dis[u]+res+w)
    
# for i in range(n):
#   # 备份,更改在下题的情况
#   # bellman - ford算法擅长解决有边数限制的最短路问题
#   pre_dis = list(dis)
#   for u,v,w in G:
#     res = c[v]
#     if v == n:
#       res = 0
#     dis[v] = min(dis[v],pre_dis[u]+res+w)

print(dis[-1])

2\853. 有边数限制的最短路

https://www.acwing.com/problem/content/855/

在这里插入图片描述

n,m,k = map(int,input().split())
G = []
for i in range(m):
    G.append(tuple(map(int,input().split())))
    
dist = [float('inf') for i in range(n+1)]
dist[1] = 0
for i in range(k):
    # 备份
    # bellman - ford算法擅长解决有边数限制的最短路问题
    pre_dist = dist[:]
    for u,v,w in G:
        dist[v] = min(dist[v],pre_dist[u]+w)
if dist[n]!=float('inf'):
    print(dist[n])
else:
    print('impossible')

SPFA(对 Bellman-Ford 算法做一个优化)

1.随机数据下的最短路问题

https://www.lanqiao.cn/problems/1366/learning/?page=1&first_category_id=1&name=%E9%9A%8F%E6%9C%BA%E6%95%B0%E6%8D%AE%E4%B8%8B%E7%9A%84

在这里插入图片描述

from collections import deque

def spfa(s):
  dq = deque()
  done = [0 for i in range(n+1)]
  dq.append(s)
  dis[s] = 0
  # done[s] = 1
  while dq:
    u = dq.popleft()
    # 访问过的都设置为0如果再
    done[u] = 0
    for v,w in G[u]:
      if dis[v]>dis[u]+w:
        dis[v] = dis[u]+w
        if not done[v]:
          done[v] = 1
          dq.append(v)

n,m,s = map(int,input().split())
G = [[] for i in range(n+1)]
for i in range(m):
  u,v,w = map(int,input().split())
  G[u].append((v,w))
dis = [float('inf') for i in range(n+1)]
spfa(s)
res = []
for i in range(1,n+1):
  res.append(-1 if dis[i]==float('inf') else dis[i])
print(*res)

2.\851. spfa求最短路

https://www.acwing.com/problem/content/853/

在这里插入图片描述

from collections import deque

def spfa(s):
    dq = deque()
    done = [0 for i in range(n+1)]
    dist[s] = 0
    dq.append(s)
    while dq:
        u = dq.popleft()
        done[u] = 0
        for v,w in G[u]:
            if dist[v]>dist[u]+w:
                dist[v]=dist[u]+w
                if not done[v]:
                    done[v] = 1
                    dq.append(v)

n,m = map(int,input().split())
G = [[] for i in range(n+1)]
for i in range(m):
    u,v,w = map(int,input().split())
    G[u].append((v,w))
    
dist = [float('inf') for i in range(n+1)]
spfa(1)
print(dist[n]) if dist[n]!=float('inf') else print('impossible')

3.\852. spfa判断负环

https://www.acwing.com/problem/content/854/

在这里插入图片描述

方法一:

统计每个点入队的次数,如果某个点入队n次,则说明存在负环

from collections import deque

def spfa(s):
    dq = deque()
    done = [0 for i in range(n+1)]
    dist[s] = 0
    dq.append(s)
    cnt[s] += 1
    while dq:
        u = dq.popleft()
        if cnt[u]>=n:
            return True
        done[u] = 0
        for v,w in G[u]:
            if dist[v]>dist[u]+w:
                dist[v]=dist[u]+w
                if not done[v]:
                    done[v] = 1
                    # 累计入队次数
                    cnt[v] += 1
                    dq.append(v)
    return False

n,m = map(int,input().split())
G = [[] for i in range(n+1)]
for i in range(m):
    u,v,w = map(int,input().split())
    G[u].append((v,w))
for i in range(1,n+1):
    G[0].append((i,0))
dist = [float('inf') for i in range(n+1)]
cnt = [0 for i in range(n+1)]
print('Yes' if spfa(0) else 'No')
方法二:

统计当前每个点的最短路中所包含的边数,如果某点的最短路所包含的边数大于等于n,则也说明存在环

dist数组初始化为0即可

from collections import deque

def spfa():
    dq = deque()
    done = [0 for i in range(n+1)]
    for i in range(1,n+1):
        dq.append(i)
        done[i] = 1
    while dq:
        u = dq.popleft()
        done[u] = 0
        for v,w in G[u]:
            if dist[v]>dist[u]+w:
                # 增加边数
                cnt[v]=cnt[u]+1
                if cnt[v]>=n:
                    return True
                dist[v]=dist[u]+w
                if not done[v]:
                    done[v] = 1
                    dq.append(v)
    return False

n,m = map(int,input().split())
G = [[] for i in range(n+1)]
for i in range(m):
    u,v,w = map(int,input().split())
    G[u].append((v,w))
dist = [0 for i in range(n+1)]
cnt = [0 for i in range(n+1)]

print('Yes' if spfa() else 'No')

4.\904. 虫洞(判负环)

https://www.acwing.com/problem/content/description/906/

在这里插入图片描述

from collections import deque

# 判断负环
def spfa():
    dq = deque()
    done = [0 for i in range(N+1)]
    dist = [0 for i in range(N+1)]
    cnt = [0 for i in range(N+1)]
    for i in range(1,N+1):
        dq.append(i)
        done[i] = 1
    while dq:
        u = dq.popleft()
        done[u] = 0
        for v,w in G[u]:
            if dist[v]>dist[u]+w:
                # 增加边数
                cnt[v]=cnt[u]+1
                if cnt[v]>=N:
                    return True
                dist[v]=dist[u]+w
                if not done[v]:
                    done[v] = 1
                    dq.append(v)
    return False
    
F = int(input())
for _ in range(F):
    N,M,W = map(int,input().split())
    G = [[] for i in range(N+1)]
    for i in range(M):
        u,v,w = map(int,input().split())
        G[u].append((v,w))
        G[v].append((u,w))
    for i in range(W):
        u,v,w = map(int,input().split())
        G[u].append((v,-w))
    print('YES' if spfa() else 'NO')

floyd

1.蓝桥公园

https://www.lanqiao.cn/problems/1121/learning/?page=1&first_category_id=1&name=%E8%93%9D%E6%A1%A5%E5%85%AC%E5%9B%AD

在这里插入图片描述

n,m,q = map(int,input().split())
dist = [[float('inf')]*(n+1) for i in range(n+1)]
for i in range(m):
  u,v,w = map(int,input().split())
  # 判重
  if dist[u][v] > w:
    dist[u][v] = w
    dist[v][u] = w

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

for i in range(q):
  u,v = map(int,input().split())
  print(-1 if dist[u][v]==float('inf') else dist[u][v])
  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值