A series of highways connect n cities numbered from 0 to n - 1. You are given a 2D integer array highways where highways[i] = [city1i, city2i, tolli] indicates that there is a highway that connects city1i and city2i, allowing a car to go from city1i to city2i and vice versa for a cost of tolli.
You are also given an integer discounts which represents the number of discounts you have. You can use a discount to travel across the ith highway for a cost of tolli / 2 (integer division). Each discount may only be used once, and you can only use at most one discount per highway.
Return the minimum total cost to go from city 0 to city n - 1, or -1 if it is not possible to go from city 0 to city n - 1.
💡 Note:Optimal path: 0→1→3→4. Without discount: 4+6+2=12. With discount on highway (1,3) with toll 6: 4+3+2=9. This is better than path 0→1→2→3→4 which costs 4+3+8+2=17, or 4+3+4+2=13 with discount on (2,3).
Minimum Cost to Reach City With Discounts — Solution
The key insight is to treat each (city, remaining_discounts) pair as a unique state in Dijkstra's algorithm. For each highway, we consider both using and not using a discount, ensuring we find the minimum cost path. Best approach uses Modified Dijkstra with state tracking. Time: O((V+E)*D*log(V*D)), Space: O(V*D)
Common Approaches
✓
DFS with Backtracking
⏱️ Time: O(2^E)
Space: O(n)
Use depth-first search to explore every possible path from city 0 to city n-1, trying both discounted and non-discounted options for each highway. Keep track of minimum cost found.
Extend Dijkstra's shortest path algorithm to track both current city and remaining discounts. Each state (city, discounts_left) is processed to find optimal path considering discount usage.
DFS with Backtracking — Algorithm Steps
Step 1: Build adjacency list from highways
Step 2: Use DFS to explore all paths with remaining discounts
Step 3: For each edge, try both with and without discount
Step 4: Track minimum cost to reach destination
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Start DFS
Begin at city 0 with all discounts available
2
Branch Paths
For each highway, try both with and without discount
3
Track Minimum
Keep track of minimum cost found to destination
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MAX_CITIES 1000
#define MAX_HIGHWAYS 10000
typedef struct {
int neighbor;
int toll;
} Edge;
typedef struct {
Edge edges[MAX_HIGHWAYS];
int count;
} AdjList;
static AdjList graph[MAX_CITIES];
static int visited[MAX_CITIES];
int dfs(int city, int target, int remainingDiscounts, int n) {
if (city == target) return 0;
int minCost = INT_MAX;
for (int i = 0; i < graph[city].count; i++) {
int neighbor = graph[city].edges[i].neighbor;
int toll = graph[city].edges[i].toll;
if (visited[neighbor]) continue;
visited[neighbor] = 1;
// Try without discount
int cost = dfs(neighbor, target, remainingDiscounts, n);
if (cost != INT_MAX) {
if (toll + cost < minCost) {
minCost = toll + cost;
}
}
// Try with discount if available
if (remainingDiscounts > 0) {
cost = dfs(neighbor, target, remainingDiscounts - 1, n);
if (cost != INT_MAX) {
if (toll / 2 + cost < minCost) {
minCost = toll / 2 + cost;
}
}
}
visited[neighbor] = 0;
}
return minCost;
}
int solution(int n, int highways[][3], int highwayCount, int discounts) {
if (n == 1) return 0;
// Initialize graph
for (int i = 0; i < n; i++) {
graph[i].count = 0;
visited[i] = 0;
}
// Build adjacency list
for (int i = 0; i < highwayCount; i++) {
int city1 = highways[i][0];
int city2 = highways[i][1];
int toll = highways[i][2];
graph[city1].edges[graph[city1].count] = (Edge){city2, toll};
graph[city1].count++;
graph[city2].edges[graph[city2].count] = (Edge){city1, toll};
graph[city2].count++;
}
visited[0] = 1;
int result = dfs(0, n - 1, discounts, n);
return result == INT_MAX ? -1 : result;
}
int main() {
int n, discounts;
scanf("%d", &n);
getchar(); // consume newline
char line[10000];
fgets(line, sizeof(line), stdin);
static int highways[MAX_HIGHWAYS][3];
int highwayCount = 0;
// Parse highways array
int len = strlen(line);
if (len > 3) { // not just "[]\n"
char *ptr = line;
while (*ptr) {
if (*ptr == '[' && *(ptr+1) != ']') {
ptr++; // skip '['
char *endptr;
// Parse first number
highways[highwayCount][0] = (int)strtol(ptr, &endptr, 10);
ptr = endptr;
// Skip comma
while (*ptr == ',' || *ptr == ' ') ptr++;
// Parse second number
highways[highwayCount][1] = (int)strtol(ptr, &endptr, 10);
ptr = endptr;
// Skip comma
while (*ptr == ',' || *ptr == ' ') ptr++;
// Parse third number
highways[highwayCount][2] = (int)strtol(ptr, &endptr, 10);
ptr = endptr;
highwayCount++;
// Skip to next '[' or end
while (*ptr && *ptr != '[') ptr++;
} else {
ptr++;
}
}
}
scanf("%d", &discounts);
int result = solution(n, highways, highwayCount, discounts);
printf("%d\n", result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(2^E)
For each edge, we try 2 options (discount or not), leading to exponential combinations
n
2n
✓ Linear Growth
Space Complexity
O(n)
Recursion stack depth can go up to n cities in the worst case
n
2n
⚡ Linearithmic Space
28.5K Views
MediumFrequency
~25 minAvg. Time
890 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.