电动车游城市
这题的思路就是需要进行拆点,即将一个单元节点拆分成多个。由于每一个节点处,可以有(cnt + 1)种加油量,即可以将一个原始点拆成独立的(cnt + 1)个点。
具体的:
1.建立邻接表
2.单源最短路径,采用最小堆实现
3.记忆化,剪枝
from collections import defaultdict
from heapq import *
class Solution:
def electricCarPlan(self, paths: List[List[int]], cnt: int, start: int, end: int, charge: List[int]) -> int:
d = defaultdict(list)
for u, v, w in paths:
d[u].append((v, w))
d[v].append((u, w))
pq = [(0, start, 0)] # cost, battery, node
memo = [[float('inf')] * (cnt + 1) for _ in range(len(paths))]
memo[start][0] = 0
while pq:
value, node, v = heappop(pq)
if node == end: return value
# if value > memo[node][v]: continue #可以不加这条判断
if v < cnt:
if value + charge[node] < memo[node][v + 1]:
memo[node][v + 1] = value + charge[node]
heappush(pq, (value + charge[node], node, v + 1))
for nex, dis in d[node]:
if dis <= v and value + dis < memo[nex][v - dis]:
memo[nex][v - dis] = value + dis
heappush(pq, (value + dis, nex, v - dis))
return -1
注意:本题案例中两点之间可能存在重边,因此建立邻接表的时候不能使用defaultdict(dict),而应该用defaultdict(list)!!!