Skip to main content
Back to problems
#3928
Hard Algorithms

Minimum cost to buy apples ii

31.2% acceptance
May 13, 2026
31
1
You are given an integer n and an integer array prices of length n, where prices[i] is the price of apples at shop i. You are also given a 2D integer array roads, where roads[i] = [ui, vi, costi, taxi] represents a bidirectional road: ui and vi are the shops connected by the road. costi is the cost to travel the road without carrying apples. taxi is the multiplier applied to costi when traveling with apples. For each shop i, you can either: Buy apples locally at shop i for prices[i]. Travel empty to any shop j using any number of roads, buy apples for prices[j], and return to shop i while carrying apples, paying cost * tax on each road used for the return trip. The forward path, where you travel empty, and the return path may be different. Return an integer array ans of length n, where ans[i] is the minimum total cost to buy apples starting from shop i.

Solution

Rust
Time O(n²)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn min_cost(n: i32, prices: Vec<i32>, roads: Vec<Vec<i32>>) -> Vec<i32> {
    use std::collections::BinaryHeap;
    use std::cmp::Reverse;
    let n = n as usize;
    let mut adj: Vec<Vec<(usize, i64, i64)>> = vec![Vec::new(); n];
    for r in &roads {
      let (u, v, c, t) = (r[0] as usize, r[1] as usize, r[2] as i64, r[3] as i64);
      adj[u].push((v, c, c * t));
      adj[v].push((u, c, c * t));
    }
    const INF: i64 = i64::MAX / 4;
    let dijkstra = |start: usize, use_tax: bool, adj: &Vec<Vec<(usize, i64, i64)>>| -> Vec<i64> {
      let n = adj.len();
      let mut dist = vec![INF; n];
      dist[start] = 0;
      let mut heap: BinaryHeap<Reverse<(i64, usize)>> = BinaryHeap::new();
      heap.push(Reverse((0, start)));
      while let Some(Reverse((d, u))) = heap.pop() {
        if d > dist[u] { continue; }
        for &(v, c, ct) in &adj[u] {
          let w = if use_tax { ct } else { c };
          let nd = d + w;
          if nd < dist[v] {
            dist[v] = nd;
            heap.push(Reverse((nd, v)));
          }
        }
      }
      dist
    };
    let mut ans: Vec<i64> = prices.iter().map(|&x| x as i64).collect();
    for j in 0..n {
      let d1 = dijkstra(j, false, &adj);
      let d2 = dijkstra(j, true, &adj);
      let pj = prices[j] as i64;
      for i in 0..n {
        if d1[i] < INF && d2[i] < INF {
          let cost = d1[i] + d2[i] + pj;
          if cost < ans[i] { ans[i] = cost; }
        }
      }
    }
    ans.iter().map(|&x| x as i32).collect()
  }
}