Open In App

Max Distance Query in Weighted Tree

Last Updated : 29 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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]

3

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:

  • The function first initializes an adjacency list (adj) to represent the graph.
  • It then performs DFS on each query node in the query list using the dfs function. It calculates the maximum distance covered if car started from that node and stores it in the ans vector.
    • max variable to store the maximum distance covered in the tree, initialized to 0 at the beginning of the function.
    • The function iterates through all the neighboring nodes of the current node (node) using the adjacency list adj. It skips the parent node (par) to avoid traversing back to the parent.
    • For each neighboring node, it calculates the distance covered by adding the weight of the edge (ngr[1]) to the distance covered from the recursive call of the dfs function on the neighboring node (ngr[0]). The distance covered represents the sum of edge weights along the path from the current node to the leaf node of the graph.
    • The algorithm then updates the max based on the calculated distance. If the distance is greater than or equal to the max, it assigns the distance to the max.
  • Finally, it returns the ans vector, which contains the maximum possible distance covered for each query node.

Below is the implementation of the code:

C++




// 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




// 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


Python3




# 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#




// 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 + " "); }
    }
}


Javascript




// 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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads