引入
求非负权边的单源最短路
时间复杂度 O( m l o g n mlogn mlogn)
模板
https://www.luogu.com.cn/problem/P4779
import heapq as hq def dijkstra(s): # dis表示从s到i的最短路 dis = [float('inf')] * (n + 1) # vis表示i是否出队列 vis = [0] * (n + 1) q = [] dis[s] = 0 hq.heappush(q, (0, s)) while q: d, u = hq.heappop(q) if vis[u]: continue vis[u] = 1 for v, w in g[u]: dis[v] = min(dis[v], dis[u] + w) hq.heappush(q, (dis[v], v)) for i in range(1, n + 1): if dis[i] == float('inf'): dis[i] = -1 return dis[1:] n, m, s= map(int, input().split())
g = [[] for _ in range(n + 1)]
for _ in range(m): u, v, w = map(int, input().split()) g[u].append((v, w))
print(*dijkstra(s))
实战演练
L2 001 紧急救援
维护多个数组并得到具体路径
import heapq as hq
import sys
input = sys.stdin.readline
inf = float('inf') def dijkstra(s, ed): q = [] vis = [0] * n dis = [inf] * n pre = [-1] * n cnt = [0] * n # 最短路径数量 res = [0] * n # 能召集的最大救援队数量 dis[s] = 0 cnt[s] = 1 res[s] = a[s] hq.heappush(q, (0, s)) while q: d, u = hq.heappop(q) if u == ed: return dis[ed], cnt[ed], res[ed], pre if vis[u]: continue vis[u] = 1 for (v, w) in g[u]: if dis[v] > dis[u] + w: dis[v] = dis[u] + w cnt[v] = cnt[u] res[v] = res[u] + a[v] pre[v] = u hq.heappush(q, (dis[v], v)) elif dis[v] == dis[u] + w: cnt[v] += cnt[u] # 更新最短路径数量 if res[v] < res[u] + a[v]: res[v] = res[u] + a[v] pre[v] = u return -1, -1, -1, pre n, m, s, ed = map(int, input().split())
a = list(map(int, input().split()))
g = [[] for _ in range(n)]
for _ in range(m): u, v, w = map(int, input().split()) g[u].append((v, w)) g[v].append((u, w)) # 无向图 dist, cnt, res, pre = dijkstra(s, ed)
if dist != -1: print(cnt, res) path = [] while ed != -1: # 从终点回溯路径 path.append(ed) ed = pre[ed] path.reverse() # 反转路径 print(' '.join(map(str, path)))
https://www.lanqiao.cn/problems/3818/learning/
import sys
import heapq as hq
input = sys.stdin.readline def get(c): if c == '.': return 0 else: return ord(c) - ord('A') + 1 def dijkstra(): q = [] dis = [[float('inf')] * m for _ in range(n)] vis = [[0] * m for _ in range(n)] dis[x1][y1] = 0 hq.heappush(q, (0, x1, y1)) while q: d, x, y = hq.heappop(q) if x == x2 and y == y2: return d if vis[x][y]: continue vis[x][y] = 1 for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]: nx, ny = x + dx, y + dy if 0 <= nx < n and 0 <= ny < m and a[nx][ny] != '#' and not vis[nx][ny]: dis[nx][ny] = min(dis[nx][ny], dis[x][y] + get(a[nx][ny])) hq.heappush(q, (dis[nx][ny], nx, ny)) return float('inf') n, m = map(int, input().split())
x1, y1, x2, y2 = map(int, input().split())
x1 -= 1
x2 -= 1
y1 -= 1
y2 -= 1
a = [input() for _ in range(n)]
e = int(input()) if e >= dijkstra(): print('Yes')
else: print('No')
https://ac.nowcoder.com/acm/contest/99909/E
对于每条边 ( u , v ) (u,v) (u,v),如果这条边在某条最短路上的话,则一定满足:
dis[u] + w + dis[v] == dis[n] ,即 最短路从 1 到 u ,再从 u 到 v ,再从 v 到 n 最短路从 1 到 u,再从 u 到 v,再从 v 到 n 最短路从1到u,再从u到v,再从v到n。(或者是 u , v u,v u,v反过来)
import sys
input = sys.stdin.readline
inf = float('inf')
import heapq as hp def dijkstra(s): dis = [inf] * (n + 1) vis = [0] * (n + 1) q = [(0, s)] dis[s] = 0 while q: d, u = hp.heappop(q) if vis[u]: continue vis[u] = 1 for v, w in g[u]: if dis[v] > dis[u] + w: dis[v] = dis[u] + w hp.heappush(q, (dis[v], v)) return dis t = int(input())
for _ in range(t): n, m = map(int, input().split()) g = [[] for _ in range(n + 1)] edge = [] for i in range(m): u, v, w = map(int, input().split()) g[u].append((v, w)) g[v].append((u, w)) edge.append((u, v, w)) dis1 = dijkstra(1) disn = dijkstra(n) res = [] for u, v, w in edge: # 检查是否在最短路径中 if dis1[u] != inf and disn[v] != inf and (dis1[u] + w + disn[v] == dis1[n]): res.append('1') elif dis1[v] != inf and disn[u] != inf and (dis1[v] + w + disn[u] == dis1[n]): res.append('1') else: res.append('0') print(''.join(res))
END
如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢