代码随想录算法训练营第62天 | 最短路径:dijkstra(堆优化版)+ Bellman_ford算法
47.参加科学大会
https://kamacoder.com/problempage.php?pid=1047
dijkstra(堆优化版)精讲
https://www.programmercarl.com/kamacoder/0047.参会dijkstra堆.html#思路
94.城市间货物运输 I
https://kamacoder.com/problempage.php?pid=1152
Bellman_ford 算法精讲
https://www.programmercarl.com/kamacoder/0094.城市间货物运输I.html#思路
dijkstra(堆优化版)精讲
-
优化部分:
- 用邻接列表:不需要一个一个遍历;
- 用优先堆:不需要找最小值;每次pop出来的就是最小值;
- 只需要更新mindist
点击查看代码
import heapq def dijkstra(n, m, grid, start, end): mindist = [float("inf")]*(n+1) visited = [False]*(n+1) mindist[start] = 0 pq = [(0,start)] ##堆优化 while pq: curr_val,u = heapq.heappop(pq) if visited[u]: continue for v,weight in grid[u]: ##更新堆 if not visited[v] and curr_val+weight<mindist[v]: mindist[v] = curr_val+weight heapq.heappush(pq,(mindist[v],v)) if mindist[end]==float("inf"): return -1 else: return mindist[end] def main(): n,m = map(int,input().split()) grid = [[] for _ in range(n+1)] for i in range(m): s,e,v = map(int,input().split()) grid[s].append((e,v)) res = dijkstra(n,m,grid,1,n) print(res) if __name__ == '__main__': main()
94. 城市间货物运输 I
某国为促进城市间经济交流,决定对货物运输提供补贴。共有 n 个编号为 1 到 n 的城市,通过道路网络连接,网络中的道路仅允许从某个城市单向通行到另一个城市,不能反向通行。
网络中的道路都有各自的运输成本和政府补贴,道路的权值计算方式为:运输成本 - 政府补贴。权值为正表示扣除了政府补贴后运输货物仍需支付的费用;权值为负则表示政府的补贴超过了支出的运输成本,实际表现为运输过程中还能赚取一定的收益。
请找出从城市 1 到城市 n 的所有可能路径中,综合政府补贴后的最低运输成本。如果最低运输成本是一个负数,它表示在遵循最优路径的情况下,运输过程中反而能够实现盈利。
城市 1 到城市 n 之间可能会出现没有路径的情况,同时保证道路网络中不存在任何负权回路。
Bellman_ford 算法精讲
-
核心思想:对所有边进行松弛n-1次操作(n为节点数量),从而求得目标最短路。
-
松弛:当前节点最小值更新:每个入度:
- if minDist[B]>minDist[A]+value:
minDist[B] = minDist[A]+value
- if minDist[B]>minDist[A]+value:
-
需要松弛几次才能得到起点到终点的最短距离
- 我们对所有边松弛 n-1 次 就一定能得到 起点到达 终点的最短距离。
-
停止:如果本次没有更新;就停止更新
点击查看代码
def bellman(n,m,edges,start,end): mindist = [float("inf")]*(n+1) mindist[start] = 0 ###松弛n-1次 for _ in range(n): update = False ##松弛每个边上的节点 for s,t,v in edges: if mindist[s]!=float("inf") and mindist[t]>mindist[s]+v: mindist[t] = mindist[s]+v update = True if not update: break if mindist[end]==float("inf"): return "unconnected" else: return mindist[end] def main(): n,m = map(int,input().split()) edges = [] for i in range(m): s,t,v = map(int,input().split()) edges.append((s,t,v)) res = bellman(n,m,edges,1,n) print(res) if __name__ == '__main__': main()