Open In App

Max Distance Query in Weighted Tree

Given n cities connected by ‘n – 1’ bidirectional roads, forming a connected and weighted undirected tree, q queries are given in an array query[]. Find the longest distance he can travel starting from each city given in the ‘query’ array ensuring we can visit each city at most once in each query.

Examples:



Input: n = 5, edges[][] = [[1, 5, 3], [2, 5, 3], [1, 4, 2], [5, 3, 2]], q = 4, query[] = [1, 3, 4, 5]



Output: 6 7 8 5

Explanation:

  • From city 1, longest distance is 1 -> 5 -> 2 = 6.
  • From city 3, longest distance is 3 -> 5 -> 1 -> 4 = 7.
  • From city 4, longest distance is 4 -> 1 -> 5 -> 2 = 8.
  • From city 5, longest distance is 5 -> 1 -> 4 = 5.

Approach: This can be solved with the following idea:

The simple idea is to run a dfs for every query node to find the maximum possible distance covered from every query node.

Below are the steps involved:

Below is the implementation of the code:




// C++ code for the above approach:
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Declaring the adj vector
vector<vector<vector<int> > > adj;
 
// Function to iterate for each query
long long dfs(int node, int par)
{
    long long max = 0;
 
    // Iterate in adj
    for (auto ngr : adj[node]) {
        if (ngr[0] == par)
            continue;
        long long score = ngr[1] + dfs(ngr[0], node);
 
        // Update the maximum distance
        if (score >= max) {
 
            max = score;
        }
    }
    return max;
}
 
// Function to calculate maxDistance
// for each query
vector<long long> longDis(int n, vector<vector<int> > edges,
                          int q, vector<int> query)
{
 
    // Resize the adjancy matrix
    adj.resize(n + 1);
 
    // Iterate in edges
    for (auto e : edges) {
        adj[e[0]].push_back({ e[1], e[2] });
        adj[e[1]].push_back({ e[0], e[2] });
    }
 
    vector<long long> ans;
 
    // Iterate for each query
    for (int i = 0; i < q; i++) {
 
        int sum = dfs(query[i], -1);
        ans.push_back(sum);
    }
 
    // Return the vector
    return ans;
}
 
// Driver code
int main()
{
 
    int n = 5;
    vector<vector<int> > edges = {
        { 1, 5, 3 }, { 2, 5, 3 }, { 1, 4, 2 }, { 5, 3, 2 }
    };
 
    int q = 4;
    vector<int> query = { 1, 3, 4, 5 };
 
    // Function call
    vector<long long> ans = longDis(n, edges, q, query);
 
    for (auto a : ans) {
 
        cout << a << " ";
    }
 
    return 0;
}




// Java program for the above approach
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
// Class to represent the graph node
class GraphNode {
    int node, weight;
 
    public GraphNode(int node, int weight)
    {
        this.node = node;
        this.weight = weight;
    }
}
 
public class GFG {
    // Declaring the adj list
    static List<List<GraphNode> > adj;
 
    // Function to iterate for each query
    static long dfs(int node, int par)
    {
        long max = 0;
 
        // Iterate in adj
        for (GraphNode ngr : adj.get(node)) {
            if (ngr.node == par)
                continue;
            long score = ngr.weight + dfs(ngr.node, node);
 
            // Update the maximum distance
            max = Math.max(max, score);
        }
        return max;
    }
 
    // Function to calculate maxDistance for each query
    static List<Long> longDis(int n,
                              List<List<Integer> > edges,
                              int q, List<Integer> query)
    {
        // Resize the adjacency list
        adj = new ArrayList<>(n + 1);
        for (int i = 0; i <= n; i++) {
            adj.add(new ArrayList<>());
        }
 
        // Iterate in edges
        for (List<Integer> e : edges) {
            adj.get(e.get(0)).add(
                new GraphNode(e.get(1), e.get(2)));
            adj.get(e.get(1)).add(
                new GraphNode(e.get(0), e.get(2)));
        }
 
        List<Long> ans = new ArrayList<>();
 
        // Iterate for each query
        for (int i = 0; i < q; i++) {
            long sum = dfs(query.get(i), -1);
            ans.add(sum);
        }
 
        // Return the list
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int n = 5;
        List<List<Integer> > edges = Arrays.asList(
            Arrays.asList(1, 5, 3), Arrays.asList(2, 5, 3),
            Arrays.asList(1, 4, 2), Arrays.asList(5, 3, 2));
 
        int q = 4;
        List<Integer> query = Arrays.asList(1, 3, 4, 5);
 
        // Function call
        List<Long> ans = longDis(n, edges, q, query);
 
        for (long a : ans) {
            System.out.print(a + " ");
        }
    }
}
 
// This code is contributed by Susobhan Akhuli




# Class to represent the graph node
class GraphNode:
    def __init__(self, node, weight):
        self.node = node
        self.weight = weight
 
# Declare adj globally
adj = []
 
# Function to iterate for each query
def dfs(node, par):
    max_distance = 0
 
    # Iterate in adj
    for ngr in adj[node]:
        if ngr.node == par:
            continue
        score = ngr.weight + dfs(ngr.node, node)
 
        # Update the maximum distance
        max_distance = max(max_distance, score)
 
    return max_distance
 
# Function to calculate maxDistance for each query
def long_dis(n, edges, q, query):
    # Clear adj when reusing the function
    adj.clear()
 
    # Resize the adjacency list
    for _ in range(n + 1):
        adj.append([])
 
    # Iterate in edges
    for e in edges:
        adj[e[0]].append(GraphNode(e[1], e[2]))
        adj[e[1]].append(GraphNode(e[0], e[2]))
 
    ans = []
 
    # Iterate for each query
    for i in range(q):
        max_sum = dfs(query[i], -1)
        ans.append(max_sum)
 
    # Return the array
    return ans
 
# Driver code
n = 5
edges = [
    [1, 5, 3], [2, 5, 3],
    [1, 4, 2], [5, 3, 2]
]
 
q = 4
query = [1, 3, 4, 5]
 
# Function call
result = long_dis(n, edges, q, query)
 
# Print the results
print(' '.join(map(str, result)))




// C# code for the above approach:
using System;
using System.Collections.Generic;
 
public class GFG {
    // Declaring the adj list
    static List<List<List<int> > > adj;
 
    // Function to iterate for each query
    static long DFS(int node, int par)
    {
        long max = 0;
 
        // Iterate in adj
        foreach(var ngr in adj[node])
        {
            if (ngr[0] == par)
                continue;
 
            long score = ngr[1] + DFS(ngr[0], node);
 
            // Update the maximum distance
            if (score >= max) {
                max = score;
            }
        }
 
        return max;
    }
 
    // Function to calculate maxDistance
    // for each query
    static List<long>
    LongestDistance(int n, List<List<int> > edges, int q,
                    List<int> query)
    {
        // Resize the adjancy matrix
        adj = new List<List<List<int> > >();
        for (int i = 0; i <= n; i++) {
            adj.Add(new List<List<int> >());
        }
 
        // Iterate in edges
        foreach(var e in edges)
        {
            adj[e[0]].Add(new List<int>{ e[1], e[2] });
            adj[e[1]].Add(new List<int>{ e[0], e[2] });
        }
 
        List<long> ans = new List<long>();
 
        // Iterate for each query
        for (int i = 0; i < q; i++) {
            long sum = DFS(query[i], -1);
            ans.Add(sum);
        }
 
        // Return the list
        return ans;
    }
 
    // Driver Code
    static public void Main()
    {
        int n = 5;
        List<List<int> > edges = new List<List<int> >{
            new List<int>{ 1, 5, 3 },
            new List<int>{ 2, 5, 3 },
            new List<int>{ 1, 4, 2 },
            new List<int>{ 5, 3, 2 }
        };
 
        int q = 4;
        List<int> query = new List<int>{ 1, 3, 4, 5 };
 
        // Function call
        List<long> ans
            = LongestDistance(n, edges, q, query);
 
        foreach(var a in ans) { Console.Write(a + " "); }
    }
}




// Class to represent the graph node
class GraphNode {
    constructor(node, weight) {
        this.node = node;
        this.weight = weight;
    }
}
 
// Declare adj globally
const adj = [];
 
// Function to iterate for each query
function dfs(node, par) {
    let max = 0;
 
    // Iterate in adj
    for (let ngr of adj[node]) {
        if (ngr.node === par)
            continue;
        let score = ngr.weight + dfs(ngr.node, node);
 
        // Update the maximum distance
        max = Math.max(max, score);
    }
    return max;
}
 
// Function to calculate maxDistance for each query
function longDis(n, edges, q, query) {
    // Clear adj when reusing the function
    adj.length = 0;
 
    // Resize the adjacency list
    for (let i = 0; i <= n; i++) {
        adj.push([]);
    }
 
    // Iterate in edges
    for (let e of edges) {
        adj[e[0]].push(new GraphNode(e[1], e[2]));
        adj[e[1]].push(new GraphNode(e[0], e[2]));
    }
 
    const ans = [];
 
    // Iterate for each query
    for (let i = 0; i < q; i++) {
        let sum = dfs(query[i], -1);
        ans.push(sum);
    }
 
    // Return the array
    return ans;
}
 
// Driver code
const n = 5;
const edges = [
    [1, 5, 3], [2, 5, 3],
    [1, 4, 2], [5, 3, 2]
];
 
const q = 4;
const query = [1, 3, 4, 5];
 
// Function call
const result = longDis(n, edges, q, query);
 
// Print the results
console.log(result.join(' '));

Output
6 7 8 5 






Time Complexity: O(Q * N)
Auxiliary Space: O(N * N)


Article Tags :