单源最短路
无权图最短路径
这个简单,BFS求解就好。像之前BFS章节提到的,BFS可以从一个点出发寻找无权有向或无向图的最短距离。
# look for shortest path from start -> u
queue = [(start, 0)]
vis = set([start])
while queue:
v, cost = queue.pop(0)
if v==u: return cost
for u in graph[v]:
if u in vis: continue
queue.append(u)
return -1如果要打印打印从start到u的最短路径,与之前的BFS算法一样,我们用要path来记录路径和标记已访问的点。或者如果要节省一下path中存储路径的空间,我们可以用先驱数组来表示路径(参考代码见CP-Algorithms)。
BFS求解无权图最短路径可以理解成加权图最短路径中权重均为1的特殊情况。
加权图最短路径
假设所有边的权重都>0,那么Dijkstra最短路算法是一种自然的贪心算法。
# 求"给予起点start和目的地u的最短路径"
dist = {start: 0} # 最小dist
queue = [(0, start)] # 最小dist堆
vis = set() # 访问过的点
while queue:
cost, v = heapq.heappop(queue)
if v in vis: continue
vis.add(v)
for n, wt in graph[v]:
ncost = cost + wt
if ncost < dist.get(n, float('inf')):
dist[n] = ncost
heapq.heappush(queue, (ncost, n))
return dist如果是求从start到所有点的单源最短路径,我们不要提前返回,最后在dist数组里就有所有答案。其实可以证明,Dijkstra算法解决的单源最短路径是解决一下问题的最好方法:
单源最短路(上例):给定起始点start,求到所有可达点的最短路径
单目的地最短路:把目的地当成起点,和情况1等价
给予起点和终点的最短路径:到达目的地后提前返回
用最短路算法求解shortestPath以后,记忆化DFS搜索答案。
Last updated
Was this helpful?