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])