Query to find the maximum and minimum weight between two nodes in the given tree using LCA.

Last Updated : 12 Jul, 2025

Given a tree, and the weights of all the node. Each query contains two integers u and v, the task is to find the minimum and maximum weight on the simple path between u and v (both inclusive).

Examples: 

Input: 
 


Query=[{1, 3}, {2, 4}, {3, 5}] 
Output: 
-1 5 
3 5 
-2 5 
Explanation: 
Weight on path 1 to 3 is [-1, 5, -1]. Hence, the minimum and maximum weight is -1 and 5 respectively. 
Weight on path 2 to 4 is [5, 3]. Hence, the minimum and maximum weight is 3 and 5 respectively. 
Weight on path 2 to 4 is [-1, 5, -1, -2]. Hence, the minimum and maximum weight is -2 and 5 respectively. 

Approach: The idea is to use LCA in a tree using Binary Lifting Technique. 

  • Binary Lifting is a Dynamic Programming approach where we pre-compute an array lca[i][j] where i = [1, n], j = [1, log(n)] and lca[i][j] contains 2j-th ancestor of node i. 
    • For computing the values of lca[][], the following recursion may be used

lca[i][j] = parent[i] if j = 0 and 
lca[i][j] = lca[lca[i][j – 1]][j – 1] if j > 0. 
 

  • As we will compute the lca[][] array we will also calculate the MinWeight[][] and MaxWeight[][] where MinWeight[i][j] contains the minimum weight from node i to its 2j-th ancestor, and MaxWeight[i][j] contains the maximum weight from node i to its 2j-th ancestor 
    • For computing the values of MinWeight[][] and MaxWeight[], the following recursion may be used.

MinWeight[i][j] =\begin{cases} min (weight[i], weight[parent[i]]) & \text{ ;if } j=0 \\ min( MinWeight[i][j-1], MinWeight[lca[i][j - 1]][j - 1]) & \text{ ;if } j>0 \end{cases}                 MaxWeight[i][j] =\begin{cases} max (weight[i], weight[parent[i]]) & \text{ ;if } j=0 \\ max( MaxWeight[i][j-1], MaxWeight[lca[i][j - 1]][j - 1]) & \text{ ;if } j>0 \end{cases} 

  • After precomputation we find the minimum and maximum weight between (u, v) as we find the least common ancestor of (u, v).


 

Below is the implementation of the above approach:


 

C++
// C++ Program to find the maximum and
// minimum weight between two nodes
// in the given tree using LCA

#include <bits/stdc++.h>
using namespace std;

#define MAX 1000

#define log 10 // log2(MAX)

// Array to store the level
// of each node
int level[MAX];

int lca[MAX][log];
int minWeight[MAX][log];
int maxWeight[MAX][log];

// Vector to store tree
vector<int> graph[MAX];
// Array to store weight of nodes
int weight[MAX];

void addEdge(int u, int v)
{
    graph[u].push_back(v);
    graph[v].push_back(u);
}

// Pre-Processing to calculate
// values of lca[][], MinWeight[][]
// and MaxWeight[][]
void dfs(int node, int parent, int h)
{
    // Using recursion formula to
    // calculate the values
    // of lca[][]
    lca[node][0] = parent;

    // Storing the level of
    // each node
    level[node] = h;
    if (parent != -1) 
    {
        minWeight[node][0]
            = min(weight[node], weight[parent]);
        maxWeight[node][0]
            = max(weight[node], weight[parent]);
    }

    for (int i = 1; i < log; i++) 
    {
        if (lca[node][i - 1] != -1) 
        {

            // Using recursion formula to
            // calculate the values of lca[][],
            // MinWeight[][] and MaxWeight[][]
            lca[node][i] = lca[lca[node][i - 1]][i - 1];
            minWeight[node][i]
                = min(minWeight[node][i - 1],
                      minWeight[lca[node][i - 1]][i - 1]);
            maxWeight[node][i]
                = max(maxWeight[node][i - 1],
                      maxWeight[lca[node][i - 1]][i - 1]);
        }
    }

    for (int i : graph[node]) 
    {
        if (i == parent)
            continue;
        dfs(i, node, h + 1);
    }
}

// Function to find the minimum and
// maximum weights in the given range
void findMinMaxWeight(int u, int v)
{

    int minWei = INT_MAX;
    int maxWei = INT_MIN;

    // The node which is present
    // farthest from the root node
    // is taken as v If u is
    // farther from root node
    // then swap the two
    if (level[u] > level[v])
        swap(u, v);

    // Finding the ancestor of v
    // which is at same level as u
    for (int i = log - 1; i >= 0; i--) 
    {

        if (lca[v][i] != -1
            && level[lca[v][i]] >= level[u]) 
        {

            // Calculating Minimum and
            // Maximum Weight of node
            // v till its 2^i-th ancestor
            minWei = min(minWei, minWeight[v][i]);
            maxWei = max(maxWei, maxWeight[v][i]);
            v = lca[v][i];
        }
    }

    // If u is the ancestor of v
    // then u is the LCA of u and v
    if (v == u) 
    {
        cout << minWei << " " << maxWei << endl;
    }

    else {

        // Finding the node closest to the
        // root which is not the common
        // ancestor of u and v i.e. a node
        // x such that x is not the common
        // ancestor of u and v but lca[x][0] is
        for (int i = log - 1; i >= 0; i--) 
        {

            if (lca[v][i] != lca[u][i]) 
            {

                // Calculating the minimum of
                // MinWeight of v to its 2^i-th
                // ancestor and MinWeight of u
                // to its 2^i-th ancestor
                minWei = min(minWei, min(minWeight[v][i],
                                         minWeight[u][i]));

                // Calculating the maximum of
                // MaxWeight of v to its 2^i-th
                // ancestor and MaxWeight of u
                // to its 2^i-th ancestor
                maxWei = max(maxWei, max(maxWeight[v][i],
                                         maxWeight[u][i]));

                v = lca[v][i];
                u = lca[u][i];
            }
        }

        // Calculating the Minimum of
        // first ancestor of u and v
        minWei = min(minWei,
                     min(minWeight[v][0], minWeight[u][0]));

        // Calculating the maximum of
        // first ancestor of u and v
        maxWei = max(maxWei,
                     max(maxWeight[v][0], maxWeight[u][0]));

        cout << minWei << " " << maxWei << endl;
    }
}

// Driver Code
int main()
{

    // Number of nodes
    int n = 5;

    // Add edges
    addEdge(1, 2);
    addEdge(1, 5);
    addEdge(2, 4);
    addEdge(2, 3);

    weight[1] = -1;
    weight[2] = 5;
    weight[3] = -1;
    weight[4] = 3;
    weight[5] = -2;

    // Initialising lca values with -1
    // Initialising MinWeight values
    // with INT_MAX
    // Initialising MaxWeight values
    // with INT_MIN
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < log; j++) {
            lca[i][j] = -1;
            minWeight[i][j] = INT_MAX;
            maxWeight[i][j] = INT_MIN;
        }
    }

    // Perform DFS
    dfs(1, -1, 0);

    // Query 1: {1, 3}
    findMinMaxWeight(1, 3);

    // Query 2: {2, 4}
    findMinMaxWeight(2, 4);

    // Query 3: {3, 5}
    findMinMaxWeight(3, 5);

    return 0;
}
Java
// Java Program to find the maximum and
// minimum weight between two nodes
// in the given tree using LCA
import java.util.*;
class GFG{

static final int MAX = 1000;

// Math.log(MAX)
static final int log = 10 ;

// Array to store the 
// level of each node
static int []level = 
       new int[MAX];

static int [][]lca = 
       new int[MAX][log];
static int [][]minWeight = 
       new int[MAX][log];
static int [][]maxWeight = 
       new int[MAX][log];

// Vector to store tree
static Vector<Integer> []graph = 
              new Vector[MAX];
  
// Array to store
// weight of nodes
static int []weight = 
       new int[MAX];
  
private static void swap(int x, 
                         int y) 
{
  int temp = x;
  x = y;
  y = temp;
}

static void addEdge(int u, 
                    int v)
{
  graph[u].add(v);
  graph[v].add(u);
}

// Pre-Processing to 
// calculate values of 
// lca[][], MinWeight[][]
// and MaxWeight[][]
static void dfs(int node, 
                int parent, int h)
{
  // Using recursion formula to
  // calculate the values
  // of lca[][]
  lca[node][0] = parent;

  // Storing the level of
  // each node
  level[node] = h;
  
  if (parent != -1) 
  {
    minWeight[node][0] = Math.min(weight[node], 
                                  weight[parent]);
    maxWeight[node][0] = Math.max(weight[node], 
                                  weight[parent]);
  }

  for (int i = 1; i < log; i++) 
  {
    if (lca[node][i - 1] != -1) 
    {
      // Using recursion formula to
      // calculate the values of lca[][],
      // MinWeight[][] and MaxWeight[][]
      lca[node][i] = 
          lca[lca[node][i - 1]][i - 1];
      
      minWeight[node][i] = 
                Math.min(minWeight[node][i - 1], 
                         minWeight[lca[node][i - 1]][i - 1]);
      maxWeight[node][i] = 
                Math.max(maxWeight[node][i - 1],
                         maxWeight[lca[node][i - 1]][i - 1]);
    }
  }

  for (int i : graph[node]) 
  {
    if (i == parent)
      continue;
    dfs(i, node, h + 1);
  }
}

// Function to find the minimum and
// maximum weights in the given range
static void findMinMaxWeight(int u, 
                             int v)
{
  int minWei = Integer.MAX_VALUE;
  int maxWei = Integer.MIN_VALUE;

  // The node which is present
  // farthest from the root node
  // is taken as v If u is
  // farther from root node
  // then swap the two
  if (level[u] > level[v])
    swap(u, v);

  // Finding the ancestor of v
  // which is at same level as u
  for (int i = log - 1; i >= 0; i--) 
  {
    if (lca[v][i] != -1 && 
        level[lca[v][i]] >= level[u]) 
    {
      // Calculating Minimum and
      // Maximum Weight of node
      // v till its 2^i-th ancestor
      minWei = Math.min(minWei, 
                        minWeight[v][i]);
      maxWei = Math.max(maxWei, 
                        maxWeight[v][i]);
      v = lca[v][i];
    }
  }

  // If u is the ancestor of v
  // then u is the LCA of u and v
  if (v == u) 
  {
    System.out.print(minWei + " " +  
                     maxWei + "\n");
  }
  else 
  {
    // Finding the node closest to the
    // root which is not the common
    // ancestor of u and v i.e. a node
    // x such that x is not the common
    // ancestor of u and v but lca[x][0] is
    for (int i = log - 1; i >= 0; i--) 
    {
      if(v == -1)
        v++;
      if (lca[v][i] != lca[u][i]) 
      {
        // Calculating the minimum of
        // MinWeight of v to its 2^i-th
        // ancestor and MinWeight of u
        // to its 2^i-th ancestor
        minWei = Math.min(minWei, 
                          Math.min(minWeight[v][i], 
                                   minWeight[u][i]));

        // Calculating the maximum of
        // MaxWeight of v to its 2^i-th
        // ancestor and MaxWeight of u
        // to its 2^i-th ancestor
        maxWei = Math.max(maxWei, 
                          Math.max(maxWeight[v][i],
                                   maxWeight[u][i]));

        v = lca[v][i];
        u = lca[u][i];
      }
    }

    // Calculating the Minimum of
    // first ancestor of u and v
    if(u == -1)
      u++;
    minWei = Math.min(minWei,
                      Math.min(minWeight[v][0], 
                               minWeight[u][0]));

    // Calculating the maximum of
    // first ancestor of u and v
    maxWei = Math.max(maxWei,
                      Math.max(maxWeight[v][0], 
                               maxWeight[u][0]));

    System.out.print(minWei + " " +  
                     maxWei + "\n");
  }
}

// Driver Code
public static void main(String[] args)
{
  // Number of nodes
  int n = 5;
  
  for (int i = 0; i < graph.length; i++)
    graph[i] = new Vector<Integer>();
  
  // Add edges
  addEdge(1, 2);
  addEdge(1, 5);
  addEdge(2, 4);
  addEdge(2, 3);

  weight[1] = -1;
  weight[2] = 5;
  weight[3] = -1;
  weight[4] = 3;
  weight[5] = -2;

  // Initialising lca values with -1
  // Initialising MinWeight values
  // with Integer.MAX_VALUE
  // Initialising MaxWeight values
  // with Integer.MIN_VALUE
  for (int i = 1; i <= n; i++) 
  {
    for (int j = 0; j < log; j++) 
    {
      lca[i][j] = -1;
      minWeight[i][j] = Integer.MAX_VALUE;
      maxWeight[i][j] = Integer.MIN_VALUE;
    }
  }

  // Perform DFS
  dfs(1, -1, 0);

  // Query 1: {1, 3}
  findMinMaxWeight(1, 3);

  // Query 2: {2, 4}
  findMinMaxWeight(2, 4);

  // Query 3: {3, 5}
  findMinMaxWeight(3, 5);
}
}

// This code is contributed by Rajput-Ji 
Python3
# Python3 Program to find the
# maximum and minimum weight 
# between two nodes in the 
# given tree using LCA
import sys
MAX = 1000
 
# log2(MAX)
log = 10 
 
# Array to store the level
# of each node
level = [0 for i in range(MAX)];

# Initialising lca values with -1
# Initialising MinWeight values
# with INT_MAX
# Initialising MaxWeight values
# with INT_MIN
lca = [[-1 for j in range(log)] 
           for i in range(MAX)]
minWeight = [[sys.maxsize for j in range(log)] 
                          for i in range(MAX)]
maxWeight = [[-sys.maxsize for j in range(log)] 
                           for i in range(MAX)]
 
# Vector to store tree
graph = [[] for i in range(MAX)]

# Array to store weight of nodes
weight = [0 for i in range(MAX)]

def addEdge(u, v):

    graph[u].append(v);
    graph[v].append(u);

# Pre-Processing to calculate
# values of lca[][], MinWeight[][]
# and MaxWeight[][]
def dfs(node, parent, h):

    # Using recursion formula to
    # calculate the values
    # of lca[][]
    lca[node][0] = parent;
 
    # Storing the level of
    # each node
    level[node] = h;
    
    if (parent != -1):    
        minWeight[node][0] = (min(weight[node], 
                                  weight[parent]));
        maxWeight[node][0] = (max(weight[node], 
                                  weight[parent]));    
    
    for i in range(1, log):
        if (lca[node][i - 1] != -1):
 
            # Using recursion formula to
            # calculate the values of lca[][],
            # MinWeight[][] and MaxWeight[][]
            lca[node][i] = lca[lca[node][i - 1]][i - 1];
            minWeight[node][i] = min(minWeight[node][i - 1],
                                     minWeight[lca[node][i - 1]][i - 1]);
            maxWeight[node][i] = max(maxWeight[node][i - 1],
                                     maxWeight[lca[node][i - 1]][i - 1]);
    
    for i in graph[node]:   
        if (i == parent):
            continue;
        dfs(i, node, h + 1);

# Function to find the minimum
# and maximum weights in the 
# given range
def findMinMaxWeight(u, v):
 
    minWei = sys.maxsize
    maxWei = -sys.maxsize
 
    # The node which is present
    # farthest from the root node
    # is taken as v If u is
    # farther from root node
    # then swap the two
    if (level[u] > level[v]):
        u, v = v, u        
 
    # Finding the ancestor of v
    # which is at same level as u
    for i in range(log - 1, -1, -1):
    
        if (lca[v][i] != -1 and 
            level[lca[v][i]] >= 
            level[u]):
 
            # Calculating Minimum and
            # Maximum Weight of node
            # v till its 2^i-th ancestor
            minWei = min(minWei, 
                         minWeight[v][i]);
            maxWei = max(maxWei, 
                         maxWeight[v][i]);
            v = lca[v][i];        
 
    # If u is the ancestor of v
    # then u is the LCA of u and v
    if (v == u):         
        print(str(minWei) + ' ' + 
              str(maxWei))
 
    else:
 
        # Finding the node closest to the
        # root which is not the common
        # ancestor of u and v i.e. a node
        # x such that x is not the common
        # ancestor of u and v but lca[x][0] is
        for i in range(log - 1, -1, -1):
 
            if (lca[v][i] != lca[u][i]): 
 
                # Calculating the minimum of
                # MinWeight of v to its 2^i-th
                # ancestor and MinWeight of u
                # to its 2^i-th ancestor
                minWei = (min(minWei, 
                              min(minWeight[v][i],
                                  minWeight[u][i])));
 
                # Calculating the maximum of
                # MaxWeight of v to its 2^i-th
                # ancestor and MaxWeight of u
                # to its 2^i-th ancestor
                maxWei = max(maxWei, 
                             max(maxWeight[v][i],
                                 maxWeight[u][i]));
 
                v = lca[v][i];
                u = lca[u][i];        
 
        # Calculating the Minimum of
        # first ancestor of u and v
        minWei = min(minWei,
                     min(minWeight[v][0], 
                         minWeight[u][0]));
 
        # Calculating the maximum of
        # first ancestor of u and v
        maxWei = max(maxWei,
                     max(maxWeight[v][0],
                         maxWeight[u][0]));
        
        print(str(minWei) + ' ' + 
              str(maxWei))    

# Driver code
if __name__ == "__main__":
    
    # Number of nodes
    n = 5;
 
    # Add edges
    addEdge(1, 2);
    addEdge(1, 5);
    addEdge(2, 4);
    addEdge(2, 3);
 
    weight[1] = -1;
    weight[2] = 5;
    weight[3] = -1;
    weight[4] = 3;
    weight[5] = -2;
 
 
    # Perform DFS
    dfs(1, -1, 0);
 
    # Query 1: {1, 3}
    findMinMaxWeight(1, 3);
 
    # Query 2: {2, 4}
    findMinMaxWeight(2, 4);
 
    # Query 3: {3, 5}
    findMinMaxWeight(3, 5);
 
# This code is contributed by Rutvik_56
C#
// C# Program to find the 
// maximum and minimum 
// weight between two nodes
// in the given tree using LCA
using System;
using System.Collections.Generic;
class GFG{

static readonly int MAX = 1000;

// Math.Log(MAX)
static readonly int log = 10 ;

// Array to store the 
// level of each node
static int []level = 
       new int[MAX];

static int [,]lca = 
       new int[MAX, log];
static int [,]minWeight = 
       new int[MAX, log];
static int [,]maxWeight = 
       new int[MAX, log];

// List to store tree
static List<int> []graph = 
            new List<int>[MAX];
  
// Array to store
// weight of nodes
static int []weight = 
       new int[MAX];
  
private static void swap(int x, 
                         int y) 
{
  int temp = x;
  x = y;
  y = temp;
}

static void addEdge(int u, 
                    int v)
{
  graph[u].Add(v);
  graph[v].Add(u);
}

// Pre-Processing to 
// calculate values of 
// lca[,], MinWeight[,]
// and MaxWeight[,]
static void dfs(int node, 
                int parent, int h)
{
  // Using recursion formula to
  // calculate the values
  // of lca[,]
  lca[node, 0] = parent;

  // Storing the level of
  // each node
  level[node] = h;
  
  if (parent != -1) 
  {
    minWeight[node, 0] = Math.Min(weight[node], 
                                  weight[parent]);
    maxWeight[node, 0] = Math.Max(weight[node], 
                                  weight[parent]);
  }

  for (int i = 1; i < log; i++) 
  {
    if (lca[node, i - 1] != -1) 
    {
      // Using recursion formula to
      // calculate the values of lca[,],
      // MinWeight[,] and MaxWeight[,]
      lca[node, i] = 
          lca[lca[node, i - 1], 
              i - 1];
      
      minWeight[node, i] = 
                Math.Min(minWeight[node, i - 1], 
                         minWeight[lca[node, i - 1], 
                                   i - 1]);
      maxWeight[node, i] = 
                Math.Max(maxWeight[node, i - 1],
                         maxWeight[lca[node, i - 1], 
                                   i - 1]);
    }
  }

  foreach (int i in graph[node]) 
  {
    if (i == parent)
      continue;
    dfs(i, node, h + 1);
  }
}

// Function to find the minimum and
// maximum weights in the given range
static void findMinMaxWeight(int u, 
                             int v)
{
  int minWei = int.MaxValue;
  int maxWei = int.MinValue;

  // The node which is present
  // farthest from the root node
  // is taken as v If u is
  // farther from root node
  // then swap the two
  if (level[u] > level[v])
    swap(u, v);

  // Finding the ancestor of v
  // which is at same level as u
  for (int i = log - 1; i >= 0; i--) 
  {
    if (lca[v, i] != -1 && 
        level[lca[v, i]] >= level[u]) 
    {
      // Calculating Minimum and
      // Maximum Weight of node
      // v till its 2^i-th ancestor
      minWei = Math.Min(minWei, 
                        minWeight[v, i]);
      maxWei = Math.Max(maxWei, 
                        maxWeight[v, i]);
      v = lca[v, i];
    }
  }

  // If u is the ancestor of v
  // then u is the LCA of u and v
  if (v == u) 
  {
    Console.Write(minWei + " " +  
                  maxWei + "\n");
  }
  else 
  {
    // Finding the node closest to the
    // root which is not the common
    // ancestor of u and v i.e. a node
    // x such that x is not the common
    // ancestor of u and v but lca[x,0] is
    for (int i = log - 1; i >= 0; i--) 
    {
      if(v == -1)
        v++;
      if (lca[v, i] != lca[u, i]) 
      {
        // Calculating the minimum of
        // MinWeight of v to its 2^i-th
        // ancestor and MinWeight of u
        // to its 2^i-th ancestor
        minWei = Math.Min(minWei, 
                 Math.Min(minWeight[v, i], 
                          minWeight[u, i]));

        // Calculating the maximum of
        // MaxWeight of v to its 2^i-th
        // ancestor and MaxWeight of u
        // to its 2^i-th ancestor
        maxWei = Math.Max(maxWei, 
                 Math.Max(maxWeight[v, i],
                          maxWeight[u, i]));
        
        v = lca[v, i];
        u = lca[u, i];
      }
    }

    // Calculating the Minimum of
    // first ancestor of u and v
    if(u == -1)
      u++;
    minWei = Math.Min(minWei,
             Math.Min(minWeight[v, 0], 
                      minWeight[u, 0]));

    // Calculating the maximum of
    // first ancestor of u and v
    maxWei = Math.Max(maxWei,
             Math.Max(maxWeight[v, 0], 
                      maxWeight[u, 0]));

    Console.Write(minWei + " " +  
                  maxWei + "\n");
  }
}

// Driver Code
public static void Main(String[] args)
{
  // Number of nodes
  int n = 5;
  
  for (int i = 0; i < graph.Length; i++)
    graph[i] = new List<int>();
  
  // Add edges
  addEdge(1, 2);
  addEdge(1, 5);
  addEdge(2, 4);
  addEdge(2, 3);

  weight[1] = -1;
  weight[2] = 5;
  weight[3] = -1;
  weight[4] = 3;
  weight[5] = -2;

  // Initialising lca values with -1
  // Initialising MinWeight values
  // with int.MaxValue
  // Initialising MaxWeight values
  // with int.MinValue
  for (int i = 1; i <= n; i++) 
  {
    for (int j = 0; j < log; j++) 
    {
      lca[i, j] = -1;
      minWeight[i, j] = int.MaxValue;
      maxWeight[i, j] = int.MinValue;
    }
  }

  // Perform DFS
  dfs(1, -1, 0);

  // Query 1: {1, 3}
  findMinMaxWeight(1, 3);

  // Query 2: {2, 4}
  findMinMaxWeight(2, 4);

  // Query 3: {3, 5}
  findMinMaxWeight(3, 5);
}
}

// This code is contributed by Rajput-Ji
JavaScript
<script>

    // JavaScript Program to find the maximum and
    // minimum weight between two nodes
    // in the given tree using LCA
    
    let MAX = 1000;
 
    // Math.log(MAX)
    let log = 10 ;

    // Array to store the
    // level of each node
    let level = new Array(MAX);
    level.fill(0);

    let lca = new Array(MAX);
    let minWeight = new Array(MAX);
    let maxWeight = new Array(MAX);

    // Vector to store tree
    let graph = new Array(MAX);

    // Array to store
    // weight of nodes
    let weight = new Array(MAX);
    weight.fill(0);

    function addEdge(u, v)
    {
      graph[u].push(v);
      graph[v].push(u);
    }

    // Pre-Processing to
    // calculate values of
    // lca[][], MinWeight[][]
    // and MaxWeight[][]
    function dfs(node, parent, h)
    {
      // Using recursion formula to
      // calculate the values
      // of lca[][]
      lca[node][0] = parent;

      // Storing the level of
      // each node
      level[node] = h;

      if (parent != -1)
      {
        minWeight[node][0] = Math.min(weight[node],
                                      weight[parent]);
        maxWeight[node][0] = Math.max(weight[node],
                                      weight[parent]);
      }

      for (let i = 1; i < log; i++)
      {
        if (lca[node][i - 1] != -1)
        {
          // Using recursion formula to
          // calculate the values of lca[][],
          // MinWeight[][] and MaxWeight[][]
          lca[node][i] =
              lca[lca[node][i - 1]][i - 1];

          minWeight[node][i] =
                    Math.min(minWeight[node][i - 1],
                             minWeight[lca[node][i - 1]][i - 1]);
          maxWeight[node][i] =
                    Math.max(maxWeight[node][i - 1],
                             maxWeight[lca[node][i - 1]][i - 1]);
        }
      }

      for (let i = 0; i < graph[node].length; i++)
      {
        if (graph[node][i] == parent)
          continue;
        dfs(graph[node][i], node, h + 1);
      }
    }

    // Function to find the minimum and
    // maximum weights in the given range
    function findMinMaxWeight(u, v)
    {
      let minWei = Number.MAX_VALUE;
      let maxWei = Number.MIN_VALUE;

      // The node which is present
      // farthest from the root node
      // is taken as v If u is
      // farther from root node
      // then swap the two
      if (level[u] > level[v])
      {
        let temp = u;
        u = v;
        v = temp;
      }

      // Finding the ancestor of v
      // which is at same level as u
      for (let i = log - 1; i >= 0; i--)
      {
        if (lca[v][i] != -1 &&
            level[lca[v][i]] >= level[u])
        {
          // Calculating Minimum and
          // Maximum Weight of node
          // v till its 2^i-th ancestor
          minWei = Math.min(minWei,
                            minWeight[v][i]);
          maxWei = Math.max(maxWei,
                            maxWeight[v][i]);
          v = lca[v][i];
        }
      }

      // If u is the ancestor of v
      // then u is the LCA of u and v
      if (v == u)
      {
        document.write(minWei + " " + maxWei + "</br>");
      }
      else
      {
        // Finding the node closest to the
        // root which is not the common
        // ancestor of u and v i.e. a node
        // x such that x is not the common
        // ancestor of u and v but lca[x][0] is
        for (let i = log - 1; i >= 0; i--)
        {
          if(v == -1)
            v++;
          if (lca[v][i] != lca[u][i])
          {
            // Calculating the minimum of
            // MinWeight of v to its 2^i-th
            // ancestor and MinWeight of u
            // to its 2^i-th ancestor
            minWei = Math.min(minWei,
                              Math.min(minWeight[v][i],
                                       minWeight[u][i]));

            // Calculating the maximum of
            // MaxWeight of v to its 2^i-th
            // ancestor and MaxWeight of u
            // to its 2^i-th ancestor
            maxWei = Math.max(maxWei,
                              Math.max(maxWeight[v][i],
                                       maxWeight[u][i]));

            v = lca[v][i];
            u = lca[u][i];
          }
        }

        // Calculating the Minimum of
        // first ancestor of u and v
        if(u == -1)
          u++;
        minWei = Math.min(minWei,
                          Math.min(minWeight[v][0],
                                   minWeight[u][0]));

        // Calculating the maximum of
        // first ancestor of u and v
        maxWei = Math.max(maxWei,
                          Math.max(maxWeight[v][0],
                                   maxWeight[u][0]));

        document.write(minWei + " " + maxWei + "</br>");
      }
    }
    
    // Number of nodes
    let n = 5;

    for (let i = 0; i < graph.length; i++)
      graph[i] = [];

    // Add edges
    addEdge(1, 2);
    addEdge(1, 5);
    addEdge(2, 4);
    addEdge(2, 3);

    weight[1] = -1;
    weight[2] = 5;
    weight[3] = -1;
    weight[4] = 3;
    weight[5] = -2;

    // Initialising lca values with -1
    // Initialising MinWeight values
    // with Integer.MAX_VALUE
    // Initialising MaxWeight values
    // with Integer.MIN_VALUE
    for (let i = 1; i <= n; i++)
    {
      lca[i] = new Array(log);
      minWeight[i] = new Array(log);
      maxWeight[i] = new Array(log);
      for (let j = 0; j < log; j++)
      {
        lca[i][j] = -1;
        minWeight[i][j] = Number.MAX_VALUE;
        maxWeight[i][j] = Number.MIN_VALUE;
      }
    }

    // Perform DFS
    dfs(1, -1, 0);

    // Query 1: {1, 3}
    findMinMaxWeight(1, 3);

    // Query 2: {2, 4}
    findMinMaxWeight(2, 4);

    // Query 3: {3, 5}
    findMinMaxWeight(3, 5);
    
</script>

Output
-1 5
3 5
-2 5

Time Complexity: The time taken in pre-processing is O(N logN) and every query takes O(logN) time. So the overall time complexity of the solution is O(N logN).
Auxiliary Space: O(MAX*log), for storing lca, where MAX=1000 and log=10.

Comment