We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Minimum Cost to Buy Apples

Number: 2612

Difficulty: Medium

Paid? Yes

Companies: Directi, Media.net


Problem Description

Given n cities (numbered 1..n) connected by bidirectional roads (each with an associated cost), and an apple cost at each city, you can start at any city, travel along the roads, buy exactly one apple from any city, and then return to your starting city. However, during the return trip, the cost of every road is multiplied by a factor k. For each starting city, determine the minimum total cost (travel cost for going, apple cost, plus weighted travel cost for returning) to complete the trip.


Key Insights

  • The overall cost from a starting city i when buying an apple at city j is: (normal travel cost from i to j) + appleCost[j] + (k * return travel cost from j to i).
  • Because the graph is undirected, the distance from i to j equals the distance from j to i.
  • The cost formula can be rewritten as appleCost[j] + (1+k)*d(i,j). Thus, for every start city i, we want the minimum value among all j.
  • We can solve this as a multi‐source shortest path problem: treat every city j as a source with an initial distance equal to appleCost[j] and “edge weight” equal to (1+k)*cost.
  • A multi‐source Dijkstra’s algorithm using a min-heap will efficiently compute the answer for every city.

Space and Time Complexity

Time Complexity: O(E log V), where E is the number of roads and V is the number of cities. Space Complexity: O(V + E) for storing the distances, graph, and the heap.


Solution

We first observe that the total cost from a starting city i if an apple is bought at city j is:   appleCost[j] + (1+k)*distance(i, j).

Thus, if we define a modified “distance” measure where each road cost is scaled by (1+k), the problem becomes: For each city i, what is the minimal value of appleCost[j] + (1+k)*d(i, j) over all cities j? This is a standard multi-source shortest path problem.

To efficiently solve it, we:

  1. Build an adjacency list for the graph.
  2. Initialize a distance/cost array with distance[i] = appleCost[i] for every city i (treating each city as a source).
  3. Use a min-heap (priority queue) and push all cities with their initial cost.
  4. Process the heap: for each popped city u with cost d, relax each neighbor v with the edge weight (1+k)*roadCost. If d + (1+k)*roadCost < distance[v], update distance[v] and push the new cost.
  5. At the end, distance[i] will represent the minimum total cost from i (starting city) to perform the trip (buying an apple somewhere and returning).

This method efficiently computes the answer for every starting city.


Code Solutions

import heapq

def minimumCostToBuyApples(n, roads, appleCost, k):
    # Build adjacency list for the graph (1-indexed)
    graph = [[] for _ in range(n+1)]
    for u, v, cost in roads:
        graph[u].append((v, cost))
        graph[v].append((u, cost))
    
    # Modified multiplier for each road on both trips
    multiplier = 1 + k

    # Initialize distances: cost to 'buy and return' if apple is bought in the same city
    dist = [float('inf')] * (n + 1)
    
    # Use multi-source Dijkstra with all cities as sources.
    # Heap elements: (current_cost, city)
    heap = []
    for city in range(1, n+1):
        dist[city] = appleCost[city-1]
        heapq.heappush(heap, (dist[city], city))
    
    # Dijkstra algorithm:
    while heap:
        current_cost, city = heapq.heappop(heap)
        if current_cost != dist[city]:
            continue
        # Relaxation loop for all neighbors
        for neighbor, road_cost in graph[city]:
            new_cost = current_cost + multiplier * road_cost
            if new_cost < dist[neighbor]:
                dist[neighbor] = new_cost
                heapq.heappush(heap, (new_cost, neighbor))
    
    # Return results excluding index 0 (convert to 0-indexed result array)
    return dist[1:]

# Example usage:
n = 4
roads = [[1,2,4],[2,3,2],[2,4,5],[3,4,1],[1,3,4]]
appleCost = [56,42,102,301]
k = 2
print(minimumCostToBuyApples(n, roads, appleCost, k))  # Expected output: [54, 42, 48, 51]
← Back to All Questions