题目描述
思路分析
首先要清楚的是,给出的特殊路径中起点并不重要,重要的是这些特殊路径的终点。
我们将起点,特殊路径终点,终点,建模成图。(无需刻意建图)
然后跑dijkstra求最短路算法即可。
1、 我们需要dist数组(这里使用dict代替)存储当前起点到各点的最短路,算法结束后dist存储了起点到所有点的最短路
2、 优先队列存储当前不确定最短路的点,每次从队首弹出的元素是当前所有不确定最短路的点中距离起点最近的。但是从队首弹出的元素可能是早已经更新过的,所以...
3、 我们需要vis集合,用于对优先队列弹出的元素进行判重。
用从队首弹出的元素(x,y)对其他点(x2,y2)进行更新的方式: 1、 从(x,y)直接到(x2,y2) 2、 从(x,y)经过(x1,y1)使用特殊路径达到(x2,y2)
算法结束后,返回dist[target]作为答案。
代码
class Solution:
def minimumCost(self, start: List[int], target: List[int], specialRoads: List[List[int]]) -> int:
sx,sy = start
tx,ty = target
def manh(a,b,x,y):
return abs(a-x) + abs(b-y)
roads = []
for x1,y1,x2,y2,sd in specialRoads:
c = manh(x1,y1,x2,y2)
roads.append((x1,y1,x2,y2,min(c,sd)))
roads.append((sx,sy,tx,ty,manh(sx,sy,tx,ty)))
vis = set()
dist = {(sx,sy):0}
pq = [(0,sx,sy)]
while pq :
d,x,y = heappop(pq)
if (x,y) in vis :
continue
vis.add((x,y))
for x1,y1,x2,y2,c in roads:
# 从(x,y)有两个方法到达当前有向线段终点:
# 1. 从(x,y)直接过去
# 2. 从(x,y)先到有向线段起点利用特殊路径过去
to_seg_end = min(d + manh(x,y,x2,y2) , d + manh(x,y,x1,y1) + c )
if to_seg_end < dist.get((x2,y2),float('inf')) :
dist[(x2,y2)] = to_seg_end
heappush(pq,(to_seg_end,x2,y2))
return dist[(tx,ty)]