返回介绍

solution / 2000-2099 / 2093.Minimum Cost to Reach City With Discounts / README

发布于 2024-06-17 01:03:10 字数 5930 浏览 0 评论 0 收藏 0

2093. 前往目标城市的最小费用

English Version

题目描述

一组公路连接 n 个城市,城市编号为从 0 到 n - 1 。 输入包含一个二维数组 highways ,其中 highways[i] = [city1i, city2i, tolli] 表示有一条连接城市 city1i 和 city2i 的双向公路,允许汽车缴纳值为 tolli 的费用从  city1i 前往 city2i  从  city2i 前往 city1i 。

另给你一个整数 discounts 表示你最多可以使用折扣的次数。你可以使用一次折扣使通过第 ith 条公路的费用降低至 tolli / 2向下取整)。 最多只可使用 discounts 次折扣, 且 每条公路最多只可使用一次折扣

返回从城市0_ _前往城市_ _n - 1 的_ _最小费用__如果不存在从城市0_ _前往城市_ _n - 1 的路径,返回 -1 。

 

示例 1:

输入:n = 5, highways = [[0,1,4],[2,1,3],[1,4,11],[3,2,3],[3,4,2]], discounts = 1
输出:9
解释:
从 0 前往 1 ,需要费用为 4 。
从 1 前往 4 并使用一次折扣,需要费用为 11 / 2 = 5 。
从 0 前往 4 最小费用为 4 + 5 = 9 。

示例 2:

输入:n = 4, highways = [[1,3,17],[1,2,7],[3,2,5],[0,1,6],[3,0,20]], discounts = 20
输出:8
解释:
从 0 前往 1 并使用一次折扣,需要费用为 6 / 2 = 3 。
从 1 前往 2 并使用一次折扣,需要费用为 7 / 2 = 3 。
从 2 前往 3 并使用一次折扣,需要费用为 5 / 2 = 2 。
从 0 前往 3 最小费用为 3 + 3 + 2 = 8 。

示例 3:

输入:n = 4, highways = [[0,1,3],[2,3,2]], discounts = 0
输出:-1
解释:
不存在从 0 前往 3 的路径,所以返回 -1 。

 

提示:

  • 2 <= n <= 1000
  • 1 <= highways.length <= 1000
  • highways[i].length == 3
  • 0 <= city1i, city2i <= n - 1
  • city1i != city2i
  • 0 <= tolli <= 105
  • 0 <= discounts <= 500
  • 任意两个城市之间最多只有一条公路相连

解法

方法一:BFS

本题属于带限制的单源最短路问题。

class Solution:
  def minimumCost(self, n: int, highways: List[List[int]], discounts: int) -> int:
    g = defaultdict(list)
    for a, b, c in highways:
      g[a].append((b, c))
      g[b].append((a, c))
    q = [(0, 0, 0)]
    dist = [[inf] * (discounts + 1) for _ in range(n)]
    while q:
      cost, i, k = heappop(q)
      if k > discounts:
        continue
      if i == n - 1:
        return cost
      if dist[i][k] > cost:
        dist[i][k] = cost
        for j, v in g[i]:
          heappush(q, (cost + v, j, k))
          heappush(q, (cost + v // 2, j, k + 1))
    return -1
class Solution {
  public int minimumCost(int n, int[][] highways, int discounts) {
    List<int[]>[] g = new List[n];
    for (int i = 0; i < n; ++i) {
      g[i] = new ArrayList<>();
    }
    for (var e : highways) {
      int a = e[0], b = e[1], c = e[2];
      g[a].add(new int[] {b, c});
      g[b].add(new int[] {a, c});
    }
    PriorityQueue<int[]> q = new PriorityQueue<>((a, b) -> a[0] - b[0]);
    q.offer(new int[] {0, 0, 0});
    int[][] dist = new int[n][discounts + 1];
    for (var e : dist) {
      Arrays.fill(e, Integer.MAX_VALUE);
    }
    while (!q.isEmpty()) {
      var p = q.poll();
      int cost = p[0], i = p[1], k = p[2];
      if (k > discounts || dist[i][k] <= cost) {
        continue;
      }
      if (i == n - 1) {
        return cost;
      }
      dist[i][k] = cost;
      for (int[] nxt : g[i]) {
        int j = nxt[0], v = nxt[1];
        q.offer(new int[] {cost + v, j, k});
        q.offer(new int[] {cost + v / 2, j, k + 1});
      }
    }
    return -1;
  }
}
class Solution {
public:
  int minimumCost(int n, vector<vector<int>>& highways, int discounts) {
    vector<vector<pair<int, int>>> g(n);
    for (auto& e : highways) {
      int a = e[0], b = e[1], c = e[2];
      g[a].push_back({b, c});
      g[b].push_back({a, c});
    }
    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> q;
    q.push({0, 0, 0});
    vector<vector<int>> dist(n, vector<int>(discounts + 1, INT_MAX));
    while (!q.empty()) {
      auto [cost, i, k] = q.top();
      q.pop();
      if (k > discounts || dist[i][k] <= cost) continue;
      if (i == n - 1) return cost;
      dist[i][k] = cost;
      for (auto [j, v] : g[i]) {
        q.push({cost + v, j, k});
        q.push({cost + v / 2, j, k + 1});
      }
    }
    return -1;
  }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文