📅  最后修改于: 2023-12-03 15:41:50.112000             🧑  作者: Mango
这是一道GATE CS 1998年的测试题,涉及了计算机科学中的搜索算法和图遍历。以下是问题描述:
给定一张无向图,每条边都有相应的权重,且权重均为正整数。现在,请你定义一个函数 find_shortest_path(u,v)
,该函数可以计算出图上从顶点u
到顶点v
的最短路径,并返回该路径的长度。
请你写出这个函数的实现方法,并分析它的时间复杂度。
这道问题可以使用Dijkstra算法来解决。
Dijkstra算法的基本思路是,从起始点开始,维护一个集合S,表示已经找到了起始点到这些点的最短路径。初始时,集合S只包含起始点。然后,每次从集合V-S中找到距离起始点最近的一个点,将其加入集合S中,并更新所有与该点有连边的点的距离。
这里我们可以使用优先队列来实现集合V-S的维护。
具体的实现代码:
def find_shortest_path(u, v):
n = len(graph) # 图的节点数
pq = [] # 优先队列,用于维护集合V-S
heapq.heappush(pq, (0, u)) # 将起始点加入优先队列
dist = [float('inf')] * n # 初始化起始点到所有点的距离
dist[u] = 0 # 起始点到自己的距离为0
while pq:
_, node = heapq.heappop(pq) # 取出距离起始点最近的一个点
if node == v: # 如果当前点就是目标点
return dist[v] # 直接返回答案
for neighbor, weight in graph[node]: # 遍历当前点的所有邻居
if dist[node] + weight < dist[neighbor]: # 如果新路径更短
dist[neighbor] = dist[node] + weight # 更新距离
heapq.heappush(pq, (dist[neighbor], neighbor)) # 将邻居加入队列
return -1 # 如果无法到达目标点,返回-1
在上面的代码中,graph
表示输入的图,即一个邻接表。其中,graph[i]
表示节点i的所有邻居。
对于每个点,我们需要遍历它的所有邻居,因此时间复杂度为O(mlogn),其中n是节点数,m是边数。这是因为优先队列的插入和弹出操作都是O(logn)的。