本次题目都来自卡码网
47. 参加科学大会(dijkstra(堆优化版))
从 堆里取堆顶元素(小顶堆中,最小的权值在上面),就可以取到离源点最近的节点了 (未访问过的节点,不会加到堆里进行排序)
使用邻接表进行存储
import heapq
# 定义一个类来表示带权重的边
class Edge:
def __init__(self, to, val):
self.to = to # 邻接顶点
self.val = val # 边的权重
if __name__ == '__main__':
n, m = map(int, input().split())
grid = [[] for _ in range(n + 1)]
for _ in range(m):
origin, destination, val = map(int, input().split())
grid[origin].append(Edge(destination, val))
start = 1 # 起点
end = n # 终点
minDist = [float('inf')] * (n + 1) # 存储从源点到每个节点的最短距离
visited = [False] * (n + 1) # 记录顶点是否被访问过
priority_queue = [] # 优先队列中存放 pair<源点到该节点的权值,节点>
heapq.heappush(priority_queue, (0, start)) # 初始化队列,源点到源点的距离为0,所以初始为0
minDist[start] = 0 # 起始点到自身的距离为0
while priority_queue:
# 1. 第一步,选源点到哪个节点近且该节点未被访问过 (通过优先级队列来实现)
cur_dist, cur_node = heapq.heappop(priority_queue)
# 2. 第二步,该最近节点被标记访问过
if visited[cur_node]:
continue
visited[cur_node] = True
# 3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)
for edge in grid[cur_node]: # 遍历 cur指向的节点,cur指向的节点为 edge
# cur指向的节点edge.to,这条边的权值为 edge.val
if (not visited[edge.to]) and cur_dist + edge.val < minDist[edge.to]:
minDist[edge.to] = cur_dist + edge.val
heapq.heappush(priority_queue, (minDist[edge.to], edge.to))
if minDist[end] == float('inf'):
print(-1)
else:
print(minDist[end])
94. 城市间货物运输 I(Bellman_ford算法)
Bellman_ford 是可以计算 负权值的单源最短路算法。其算法核心思路是对 所有边进行 n-1 次 松弛。
对所有边松弛一次,相当于计算 起点到达 与起点一条边相连的节点 的最短距离。
无论图是什么样的,边是什么样的顺序,我们对所有边松弛 n-1 次 就一定能得到 起点到达 终点的最短距离。
下面代码超时
if __name__ == '__main__':
n, m = map(int, input().split())
grid = []
for i in range(m):
p1, p2, val = map(int, input().split())
grid.append((p1, p2, val))
start = 1 # 起点
end = n # 终点
minDist = [float('inf')] * (n + 1)
minDist[start] = 0
for _ in range(n - 1): # 对所有边 松弛 n-1 次
for side in grid: # 每一次松弛,都是对所有边进行松弛
_from = side[0] # 边的出发点
to = side[1] # 边的到达点
price = side[2] # 边的权值
# 松弛操作
# minDist[from] != INT_MAX 防止从未计算过的节点出发
if minDist[_from] != float('inf') and minDist[to] > minDist[_from] + price:
minDist[to] = minDist[_from] + price
if minDist[end] == float('inf'):
print("unconnected") # 不能到达终点
else:
print(minDist[end]) # 到达终点最短路径
、Bellman_ford算法&spm=1001.2101.3001.5002&articleId=140211307&d=1&t=3&u=fbed560ac0d14d089f5140117fb2f790)
482

被折叠的 条评论
为什么被折叠?



