📅  最后修改于: 2023-12-03 15:12:40.559000             🧑  作者: Mango
本题是GATE-CS-2003的第21个问题,考察的是图形算法的实现能力。
给定一张无向图和一个起点,对于图中每个点,计算它到起点的最短距离。图中存在负权边和自环。
n
和 m
,表示图有 n
个节点和 m
条边。m
行,每行三个整数 u
、v
和 w
,表示一条从节点 u
到节点 v
权重为 w
的无向边。输出 n
行,第 i
行表示节点 i
到起点的最短距离。
输入:
5 5
1 2 5
2 3 2
3 4 4
4 5 1
5 1 1
1
输出:
0
5
7
11
12
该问题可以通过Dijkstra算法或Bellman-Ford算法求解。这里以Dijkstra算法为例进行介绍。
Dijkstra算法是基于贪心思想的单源最短路径算法,用来求一张图中一个节点到其他所有节点的最短路径。算法维护一个集合 S
,表示已经求出最短路径的节点集合,初始时 S
中只包括起点。之后,每次选取一个距离起点最近的、且不在 S
中的点,把它加入 S
中,并用它更新与它相邻的其他节点的距离。这样,不断重复以上过程,直到把所有点都加入集合 S
中为止。
Dijkstra算法存在一个优先队列优化的实现,可以进一步加速算法的执行速度。
以下是Dijkstra算法的完整实现,使用了优先队列优化。时间复杂度为 $O(m\log n)$。
import heapq
def dijkstra(n, m, graph, start):
distances = [float('inf')] * n
distances[start] = 0
visited = [False] * n
visited[start] = True
heap = [(0, start)]
while heap:
(dist, node) = heapq.heappop(heap)
visited[node] = True
for i, weight in graph[node]:
if visited[i]:
continue
if distances[node] + weight < distances[i]:
distances[i] = distances[node] + weight
heapq.heappush(heap, (distances[i], i))
return distances
n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
u, v, w = map(int, input().split())
graph[u-1].append((v-1, w))
graph[v-1].append((u-1, w))
start = int(input()) - 1
distances = dijkstra(n, m, graph, start)
for d in distances:
print(d)
通过本题的实现,我们学习了Dijkstra算法的实现思路和代码实现。同时,我们也学习了图形算法中的贪心思想,对图形算法的理解和实现有了更深入的认识。