Python Leetcode单源最短路径之两种权值下求解最小值

电动车游城市

在这里插入图片描述
这题的思路就是需要进行拆点,即将一个单元节点拆分成多个。由于每一个节点处,可以有(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)!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值