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:
- 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++ 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( ' ' ));
|
6 7 8 5
Time Complexity: O(Q * N)
Auxiliary Space: O(N * N)