You are given an undirected weighted connected graph containing n nodes labeled from 0 to n - 1, and an integer array edges where edges[i] = [ai, bi, wi] indicates that there is an edge between nodes ai and bi with weight wi.
Some edges have a weight of -1 (wi = -1), while others have a positive weight (wi > 0).
Your task is to modify all edges with a weight of -1 by assigning them positive integer values in the range [1, 2 * 10⁹] so that the shortest distance between the nodes source and destination becomes equal to an integer target. If there are multiple modifications that make the shortest distance between source and destination equal to target, any of them will be considered correct.
Return an array containing all edges (even unmodified ones) in any order if it is possible to make the shortest distance from source to destination equal to target, or an empty array if it's impossible.
Note: You are not allowed to modify the weights of edges with initial positive weights.
💡 Note:Set the unknown edge weights so that the shortest path from node 0 to node 1 equals exactly 5. One possible solution is to set edge (0,3) to weight 3, keeping others at minimum weight 1.
G
Google 45f
Facebook 38a
Amazon 32M
Microsoft 28A
Apple 22
Modify Graph Edge Weights — Solution
The key insight is to use Dijkstra's algorithm with binary search on edge weights. First check if the target is achievable by setting all -1 edges to minimum (1) and maximum (2×10⁹) weights. Then use binary search to find the exact weight for one critical edge that makes the shortest path equal to target. Best approach is Dijkstra + Binary Search: Time O(log(2×10⁹) × (V+E) log V), Space O(V+E).
For each edge with weight -1, try all possible values from 1 to 2*10⁹. For each combination, run Dijkstra's algorithm to check if the shortest path equals the target.
First run Dijkstra with all -1 edges set to 1 to get minimum possible distance. If it's already greater than target, return empty. Then use binary search to adjust one critical edge weight to achieve exact target distance.
Brute Force with All Combinations — Algorithm Steps
Identify all edges with weight -1
Generate all possible weight combinations
For each combination, run Dijkstra's algorithm
Return first combination that achieves target distance
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Identify -1 Edges
Find all edges that need weight assignment
2
Generate Combinations
Try different weight values for each -1 edge
3
Run Dijkstra
Calculate shortest path for each combination
4
Check Target
Return first combination that matches target distance
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MAX_N 100
#define MAX_EDGES 1000
#define INF (long long)2e18
static int n, source, destination, target;
static int edges[MAX_EDGES][3];
static int graphEdges[MAX_EDGES][3];
static int negEdges[MAX_EDGES];
static int numEdges, numNegEdges;
// DIRECTED: only a->b, not b->a
long long dijkstra(int edgesList[][3], int numEdgesList) {
long long dist[MAX_N];
int visited[MAX_N] = {0};
for (int i = 0; i < n; i++) dist[i] = INF;
dist[source] = 0;
for (int count = 0; count < n; count++) {
int u = -1;
for (int i = 0; i < n; i++)
if (!visited[i] && (u == -1 || dist[i] < dist[u])) u = i;
if (u == -1 || dist[u] == INF) break;
visited[u] = 1;
for (int i = 0; i < numEdgesList; i++) {
int a = edgesList[i][0], b = edgesList[i][1], w = edgesList[i][2];
if (w <= 0) continue;
// Directed: a->b only
if (a == u && dist[u] + w < dist[b]) dist[b] = dist[u] + w;
}
}
return dist[destination] == INF ? -1 : dist[destination];
}
int solve() {
for (int i = 0; i < numNegEdges; i++) graphEdges[negEdges[i]][2] = 1;
long long minDist = dijkstra(graphEdges, numEdges);
if (minDist == -1 || minDist > (long long)target) return 0;
for (int i = 0; i < numNegEdges; i++) graphEdges[negEdges[i]][2] = 2000000000;
long long maxDist = dijkstra(graphEdges, numEdges);
if (maxDist == -1 || maxDist < (long long)target) return 0;
for (int i = 0; i < numNegEdges; i++) graphEdges[negEdges[i]][2] = 1;
for (int i = 0; i < numNegEdges; i++) {
graphEdges[negEdges[i]][2] = 1;
for (int j = i + 1; j < numNegEdges; j++)
graphEdges[negEdges[j]][2] = 2000000000;
long long dist = dijkstra(graphEdges, numEdges);
if (dist <= (long long)target) {
long long newW = 1LL + ((long long)target - dist);
if (newW > 2000000000LL) newW = 2000000000LL;
graphEdges[negEdges[i]][2] = (int)newW;
for (int j = i + 1; j < numNegEdges; j++)
graphEdges[negEdges[j]][2] = 1;
break;
}
}
return dijkstra(graphEdges, numEdges) == (long long)target;
}
void parseEdges(const char *line) {
numEdges = 0;
numNegEdges = 0;
if (strcmp(line, "[]") == 0) return;
const char *ptr = line;
while (*ptr) {
if (*ptr == '[' && *(ptr + 1) != '[') {
int a, b, w;
if (sscanf(ptr + 1, "%d,%d,%d", &a, &b, &w) == 3) {
edges[numEdges][0] = a;
edges[numEdges][1] = b;
edges[numEdges][2] = w;
graphEdges[numEdges][0] = a;
graphEdges[numEdges][1] = b;
graphEdges[numEdges][2] = (w == -1) ? 1 : w;
if (w == -1) negEdges[numNegEdges++] = numEdges;
numEdges++;
}
}
ptr++;
}
}
int main() {
scanf("%d", &n);
char line[10000];
scanf(" %[^\n]", line);
parseEdges(line);
scanf("%d", &source);
scanf("%d", &destination);
scanf("%d", &target);
if (numNegEdges == 0) {
if (dijkstra(graphEdges, numEdges) == (long long)target) {
printf("[");
for (int i = 0; i < numEdges; i++) {
if (i > 0) printf(",");
printf("[%d,%d,%d]", graphEdges[i][0], graphEdges[i][1], graphEdges[i][2]);
}
printf("]\n");
} else printf("[]\n");
return 0;
}
if (solve()) {
printf("[");
for (int i = 0; i < numEdges; i++) {
if (i > 0) printf(",");
printf("[%d,%d,%d]", graphEdges[i][0], graphEdges[i][1], graphEdges[i][2]);
}
printf("]\n");
} else printf("[]\n");
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O((2×10⁹)^k × (V + E) log V)
k is number of -1 edges, each can have 2×10⁹ values, Dijkstra runs in O((V+E) log V)
n
2n
⚡ Linearithmic
Space Complexity
O(V + E)
Graph storage and priority queue for Dijkstra's algorithm
n
2n
✓ Linear Space
23.5K Views
MediumFrequency
~35 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.