There exists an undirected and initially unrooted tree with n nodes indexed from 0 to n - 1. You are given the integer n and a 2D integer arrayedges of length n - 1, where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.
Each node has an associated price. You are given an integer array price, where price[i] is the price of the ith node.
The price sum of a given path is the sum of the prices of all nodes lying on that path.
The tree can be rooted at any node root of your choice. The incurred cost after choosing root is the difference between the maximum and minimum price sum amongst all paths starting at root.
Return the maximum possible cost amongst all possible root choices.
💡 Note:When root=0: paths [2+3=5, 2+3+1=6], cost=6-5=1. When root=1: paths [3+2=5, 3+1=4], cost=5-4=1. When root=2: path [1+3+2=6], cost=0. Maximum cost is 2 when we choose an optimal root.
Example 2 — Single Node
$Input:n = 1, edges = [], price = [5]
›Output:0
💡 Note:Only one node, so there's only one path (the node itself) with sum 5. Max - min = 5 - 5 = 0.
💡 Note:When root=0: paths [1+2=3, 1+3=4, 1+4=5], cost=5-3=2. When root=1: paths [2+1+3=6, 2+1+4=7], cost=7-6=1. When root=2: paths [3+1+2=6, 3+1+4=8], cost=8-6=2. When root=3: paths [4+1+2=7, 4+1+3=8], cost=8-7=1. Maximum cost across all roots is 2.
Difference Between Maximum and Minimum Price Sum — Solution
This problem requires finding the optimal root for a tree to maximize the difference between maximum and minimum path sums. The key insight is that we need to try each node as root and calculate all paths from root to leaves. The brute force approach works by trying all possible roots and computing path sums via DFS. Time: O(n²), Space: O(n).
Common Approaches
✓
Brute Force - Try All Roots
⏱️ Time: O(n²)
Space: O(n)
For each possible root node, build the tree rooted at that node and use DFS to find all path sums starting from the root. Calculate max - min for each root choice.
Tree Rerooting Optimization
⏱️ Time: O(n²)
Space: O(n)
First calculate the answer for one root, then efficiently transition to other roots by updating only the affected paths using tree rerooting technique.
Brute Force - Try All Roots — Algorithm Steps
Step 1: For each node as potential root
Step 2: Build adjacency list and run DFS from root
Step 3: Find all path sums from root to leaves
Step 4: Calculate max - min difference
Step 5: Track maximum difference across all roots
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Choose Root
Select each node as potential root
2
Calculate Paths
Find all paths from root to leaves using DFS
3
Find Max Cost
Calculate max - min difference for each root choice
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MAX_N 1000
#define MAX_LINE 10000
int graph[MAX_N][MAX_N];
int graphSize[MAX_N];
int price[MAX_N];
long long pathSums[MAX_N];
int pathSumsCount;
void dfs(int node, int parent, long long currentSum, int n) {
currentSum += price[node];
if (graphSize[node] == 1 && parent != -1) {
pathSums[pathSumsCount++] = currentSum;
return;
}
if (graphSize[node] == 0) {
pathSums[pathSumsCount++] = currentSum;
return;
}
for (int i = 0; i < graphSize[node]; i++) {
int neighbor = graph[node][i];
if (neighbor != parent) {
dfs(neighbor, node, currentSum, n);
}
}
}
int parseEdges(char* line, int edges[][2]) {
int count = 0;
char* ptr = line;
// Skip initial '['
while (*ptr && *ptr != '[') ptr++;
if (*ptr) ptr++;
while (*ptr) {
// Skip whitespace and commas
while (*ptr && (*ptr == ' ' || *ptr == ',' || *ptr == '\n' || *ptr == '\t')) ptr++;
if (!*ptr || *ptr == ']') break;
// Look for '['
if (*ptr == '[') {
ptr++;
// Read first number
edges[count][0] = strtol(ptr, &ptr, 10);
// Skip comma
while (*ptr && *ptr != ',') ptr++;
if (*ptr == ',') ptr++;
// Read second number
edges[count][1] = strtol(ptr, &ptr, 10);
// Skip to ']'
while (*ptr && *ptr != ']') ptr++;
if (*ptr == ']') ptr++;
count++;
} else {
ptr++;
}
}
return count;
}
void parsePrice(char* line, int priceArr[], int n) {
char* ptr = line;
int count = 0;
// Skip initial '['
while (*ptr && *ptr != '[') ptr++;
if (*ptr) ptr++;
while (*ptr && count < n) {
// Skip whitespace and commas
while (*ptr && (*ptr == ' ' || *ptr == ',' || *ptr == '\n' || *ptr == '\t')) ptr++;
if (!*ptr || *ptr == ']') break;
priceArr[count] = strtol(ptr, &ptr, 10);
count++;
}
}
long long solution(int n, int edges[][2], int edgesCount, int priceArr[]) {
// Initialize
for (int i = 0; i < n; i++) {
graphSize[i] = 0;
price[i] = priceArr[i];
}
// Build graph
for (int i = 0; i < edgesCount; i++) {
int a = edges[i][0], b = edges[i][1];
graph[a][graphSize[a]++] = b;
graph[b][graphSize[b]++] = a;
}
long long maxCost = 0;
for (int root = 0; root < n; root++) {
pathSumsCount = 0;
if (graphSize[root] == 0) {
pathSums[pathSumsCount++] = price[root];
} else {
dfs(root, -1, 0LL, n);
}
if (pathSumsCount > 0) {
long long maxSum = pathSums[0], minSum = pathSums[0];
for (int i = 1; i < pathSumsCount; i++) {
if (pathSums[i] > maxSum) maxSum = pathSums[i];
if (pathSums[i] < minSum) minSum = pathSums[i];
}
long long cost = maxSum - minSum;
if (cost > maxCost) maxCost = cost;
}
}
return maxCost;
}
int main() {
int n;
char line[MAX_LINE];
int edges[MAX_N][2];
int priceArr[MAX_N];
// Read n
scanf("%d", &n);
// Read edges line
fgets(line, MAX_LINE, stdin); // consume newline
fgets(line, MAX_LINE, stdin);
int edgesCount = parseEdges(line, edges);
// Read price line
fgets(line, MAX_LINE, stdin);
parsePrice(line, priceArr, n);
printf("%lld\n", solution(n, edges, edgesCount, priceArr));
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n²)
For each of n roots, we perform DFS traversal of n nodes
n
2n
⚠ Quadratic Growth
Space Complexity
O(n)
Adjacency list storage and DFS recursion stack
n
2n
⚡ Linearithmic Space
8.5K Views
MediumFrequency
~35 minAvg. Time
189 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.