Imagine you're a delivery driver with a special power: you can teleport through at most k roads to make them cost zero! 🚚✨
You're given an undirected weighted graph with n nodes connected by edges. Each edge has a weight representing the travel cost. Your mission is to find the shortest path from source node s to destination node d, but here's the twist: you can make up to k edges have zero weight by "hopping" over them.
Goal: Find the minimum total cost to travel from s to d when you can eliminate the cost of at most k edges.
Input: Number of nodes n, array of edges [u, v, weight], source s, destination d, and maximum hops k.
Output: The minimum path cost with the given hop constraint.
Input & Output
example_1.py — Basic Triangle Graph
$Input:n = 3, edges = [[0,1,5], [1,2,3], [0,2,8]], s = 0, d = 2, k = 1
›Output:3
💡 Note:We have a triangle: 0--(5)--1--(3)--2 with direct edge 0--(8)--2. With k=1, we can make one edge free. Best strategy: take path 0→1→2, make edge 0→1 free (cost 0), then pay 3 for edge 1→2. Total cost = 3.
example_2.py — No Hops Needed
$Input:n = 3, edges = [[0,1,1], [1,2,1], [0,2,3]], s = 0, d = 2, k = 2
›Output:2
💡 Note:Direct path 0→1→2 costs only 2, which is better than the direct edge 0→2 costing 3. Even though we have 2 hops available, we don't need to use any since the cheapest path is already optimal.
example_3.py — Use All Hops
$Input:n = 4, edges = [[0,1,10], [1,2,10], [2,3,10], [0,3,25]], s = 0, d = 3, k = 2
›Output:10
💡 Note:Path 0→1→2→3 normally costs 30. With k=2 hops, we can make edges 0→1 and 1→2 free, leaving only edge 2→3 costing 10. This beats the direct path 0→3 costing 25.
The optimal approach uses a modified Dijkstra's algorithm with state tracking. Each state represents (node, hops_remaining), and we explore both paying for edges and using free hops. This transforms the problem into shortest path search in a 3D state space with time complexity O((V + E) * K * log(V * K)).
Common Approaches
Approach
Time
Space
Notes
✓
Brute Force (Try All Hop Combinations)
O(C(E,k) * (V + E) log V)
O(V + E)
Try every possible combination of k edges to make free, then find shortest path
Modified Dijkstra with State Tracking (Optimal)
O((V + E) * K * log(V * K))
O(V * K)
Use Dijkstra's algorithm with state (node, hops_used) to find optimal path
Brute Force (Try All Hop Combinations) — Algorithm Steps
Generate all possible combinations of edges to make free (up to k edges)
For each combination, create a modified graph with selected edges having weight 0
Run Dijkstra's algorithm on each modified graph
Return the minimum path cost among all combinations
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Generate Combinations
Generate all possible combinations of k edges to make free
2
Modify Graph
For each combination, create a graph with selected edges having weight 0
3
Run Dijkstra
Find shortest path in the modified graph
4
Track Minimum
Keep track of the minimum cost found across all combinations
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
typedef struct {
int to, weight;
} Edge;
typedef struct {
Edge* edges;
int count, capacity;
} AdjList;
typedef struct {
int cost, node;
} HeapNode;
typedef struct {
HeapNode* data;
int size, capacity;
} MinHeap;
MinHeap* createHeap(int capacity) {
MinHeap* heap = (MinHeap*)malloc(sizeof(MinHeap));
heap->data = (HeapNode*)malloc(capacity * sizeof(HeapNode));
heap->size = 0;
heap->capacity = capacity;
return heap;
}
void heapifyUp(MinHeap* heap, int idx) {
if (idx && heap->data[(idx-1)/2].cost > heap->data[idx].cost) {
HeapNode temp = heap->data[idx];
heap->data[idx] = heap->data[(idx-1)/2];
heap->data[(idx-1)/2] = temp;
heapifyUp(heap, (idx-1)/2);
}
}
void heapifyDown(MinHeap* heap, int idx) {
int smallest = idx;
int left = 2*idx + 1, right = 2*idx + 2;
if (left < heap->size && heap->data[left].cost < heap->data[smallest].cost)
smallest = left;
if (right < heap->size && heap->data[right].cost < heap->data[smallest].cost)
smallest = right;
if (smallest != idx) {
HeapNode temp = heap->data[idx];
heap->data[idx] = heap->data[smallest];
heap->data[smallest] = temp;
heapifyDown(heap, smallest);
}
}
void push(MinHeap* heap, int cost, int node) {
if (heap->size < heap->capacity) {
heap->data[heap->size].cost = cost;
heap->data[heap->size].node = node;
heapifyUp(heap, heap->size);
heap->size++;
}
}
HeapNode pop(MinHeap* heap) {
HeapNode root = heap->data[0];
heap->data[0] = heap->data[heap->size-1];
heap->size--;
heapifyDown(heap, 0);
return root;
}
int dijkstra(AdjList* graph, int start, int end, int n) {
int* dist = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) dist[i] = INT_MAX;
dist[start] = 0;
MinHeap* pq = createHeap(n * n);
push(pq, 0, start);
while (pq->size > 0) {
HeapNode curr = pop(pq);
int cost = curr.cost, node = curr.node;
if (node == end) {
free(dist);
int result = cost;
free(pq->data);
free(pq);
return result;
}
if (cost > dist[node]) continue;
for (int i = 0; i < graph[node].count; i++) {
int neighbor = graph[node].edges[i].to;
int weight = graph[node].edges[i].weight;
int newCost = cost + weight;
if (newCost < dist[neighbor]) {
dist[neighbor] = newCost;
push(pq, newCost, neighbor);
}
}
}
int result = dist[end];
free(dist);
free(pq->data);
free(pq);
return result;
}
int shortestPathWithKHops(int n, int** edges, int edgesSize, int s, int d, int k) {
int minCost = INT_MAX;
// Simple implementation for small k - try all combinations
for (int mask = 0; mask < (1 << edgesSize) && __builtin_popcount(mask) <= k; mask++) {
if (__builtin_popcount(mask) > k) continue;
// Build graph with selected edges having weight 0
AdjList* graph = (AdjList*)calloc(n, sizeof(AdjList));
for (int i = 0; i < n; i++) {
graph[i].capacity = edgesSize * 2;
graph[i].edges = (Edge*)malloc(graph[i].capacity * sizeof(Edge));
}
for (int i = 0; i < edgesSize; i++) {
int u = edges[i][0], v = edges[i][1], w = edges[i][2];
int weight = (mask & (1 << i)) ? 0 : w;
graph[u].edges[graph[u].count++] = (Edge){v, weight};
graph[v].edges[graph[v].count++] = (Edge){u, weight};
}
int cost = dijkstra(graph, s, d, n);
if (cost < minCost) minCost = cost;
for (int i = 0; i < n; i++) free(graph[i].edges);
free(graph);
}
return minCost;
}
Time & Space Complexity
Time Complexity
⏱️
O(C(E,k) * (V + E) log V)
C(E,k) combinations times Dijkstra's complexity for each
n
2n
⚡ Linearithmic
Space Complexity
O(V + E)
Space for graph representation and Dijkstra's data structures
n
2n
✓ Linear Space
25.0K Views
MediumFrequency
~15 minAvg. Time
850 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.