本文共 2174 字,大约阅读时间需要 7 分钟。
为了找到从1到n的最短路径,可以将每一层和每个顶点压缩为一个节点。每一层内部的顶点连接到同一层的其他顶点,并通过网络层之间的边处理成本c。这样,可以将问题转化为带层的最短路径问题,从而高效地使用Dijkstra算法来找到最短路径。
步骤解释:
图的压缩: 将每个层视为一个节点,每层内部的顶点连接到同一层的其他顶点,添加权重为0的边。
处理层间边: 将每一层u的顶点与上下一层u+1和u-1的顶点建立权重为c的边。
初始设定: 起点为层1,终点为层n。使用优先队列执行Dijkstra算法,计算各节点的最短距离。
优化递减: 通过层分割,将问题规模降低到可处理范围,使得解决时间更为合理。
实现代码(Python):
import heapqdef main(): import sys input = sys.stdin.read().split() ptr = 0 T = int(input[ptr]) ptr += 1 max_layer = 2 * (10**5) + 2 INF = 1e18 layers = T for _ in range(T): n = int(input[ptr]) m = int(input[ptr+1]) c = int(input[ptr+2]) ptr +=3 size = 2 * n + 2 g = [[] for _ in range(size)] visited = [False]*(size) dist = [INF]*(size) for t in range(1, n+1): layer = t + n +1 # layer starts at n+2 g[layer].append( (0, t) ) g[t].append( (c, layer) ) g[t].append( (c, layer+1) ) for _ in range(m): u = int(input[ptr]) v = int(input[ptr+1]) w = int(input[ptr+2]) ptr +=3 if u <= v: g[u].append( (w, v) ) else: g[v].append( (w, u) ) dist[1] = 0 heap = [ (0, 1) ] heapq.heapify(heap) while heap: d, u = heapq.heappop(heap) if visited[u]: continue visited[u] = True if u == n +1: #目标层的第一个节点? # 出现疑问,需要确认层的编号是否正确 break for v_edge, weight in g[u]: if not visited[v_edge]: if dist[v_edge] > d + weight: dist[v_edge] = d + weight heapq.heappush(heap, (dist[v_edge], v_edge)) min_distance = dist[n] if min_distance == INF: print(-1) else: print(min_distance) return if __name__ == "__main__": main()
代码解释:
g
,将同一层的顶点连接到同一层,跨层顶点之间建立权重为c的边。通过压缩节点和使用优先队列优化,Dijkstra算法在较小的节点数规模下高效运行,解决了大规模图的最短路径问题。
转载地址:http://pzjyk.baihongyu.com/