Minimum distance to visit all the nodes of an undirected weighted tree
Last Updated :
30 Nov, 2021
Given a weighted tree with N nodes starting from 1 to N. The distance between any two nodes is given by the edge weight. Node 1 is the source, the task is to visit all the nodes of the tree with the minimum distance traveled.
Examples:
Input:
u[] = {1, 1, 2, 2, 1}
v[] = {2, 3, 5, 6, 4}
w[] = {1, 4, 2, 50, 5}
Output: 73
Input:
u[] = {1, 2}
v[] = {2, 3}
w[] = {3, 1}
Output: 4
Approach: Let’s suppose there are n leaf l1, l2, l3, ……, ln and the cost of the path from root to each leaf is c1, c2, c3, ……, cn.
To travel from l1 to l2 some of the edges will be visited twice ( till the LCA of l1 and l2 all the edges will be visited twice ), for l2 to l3 and some of the edges will be visited ( till the LCA of l2 and l3 all the edges will be visited twice ) twice and similarly every edge of the tree will be visited twice ( observation ).
To minimize the cost of travelling, the maximum cost path from the root to some leaf should be avoided.
Hence the cost = (c1 + c2 + c3 + …… + cn) – max(c1, c2, c3, ……, cn)
min cost = (2 * sum of edge weight) – max(c1, c2, c3, ……, cn)
DFS can be used with some modification to find the largest distance.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Edge{
public :
int from;
int to;
long wt;
Edge( int a, int b, long w)
{
from = a;
to = b;
wt = w;
}
};
void add_edge(vector<vector<Edge>> &adj_lis,
int to, int from, long wt)
{
adj_lis[from].push_back(Edge(from, to, wt));
adj_lis[to].push_back(Edge(to, from, wt));
}
void dfs(vector<vector<Edge>> &adj_lis,
long val[], int v, int par,
long sum, bool visited[])
{
val[v] = sum;
visited[v] = true ;
for (Edge e : adj_lis[v])
{
if (!visited[e.to])
dfs(adj_lis, val, e.to,
v, sum + e.wt, visited);
}
}
int main()
{
int v = 6;
vector<vector<Edge>> adj_lis(v);
long val[v];
bool visited[v];
int sum = 0;
int from[] = { 2, 3, 5, 6, 4 };
int to[] = { 1, 1, 2, 2, 1 };
int wt[] = { 1, 4, 2, 50, 5 };
for ( int i = 0; i < v - 1; i++)
{
sum += 2 * wt[i];
add_edge(adj_lis, to[i] - 1,
from[i] - 1, wt[i]);
}
dfs(adj_lis, val, 0, -1, 0, visited);
long large = INT_MIN;
int size = sizeof (val) / sizeof ( long );
for ( int i = 1; i < size; i++)
if (val[i] > large)
large = val[i];
cout << (sum - large);
}
|
Java
import java.util.LinkedList;
import java.util.Scanner;
class Graph {
class Edge {
int from;
int to;
long wt;
Edge( int a, int b, long w)
{
from = a;
to = b;
wt = w;
}
}
static LinkedList<Edge>[] adj_lis;
static int V;
static long val[];
Graph( int v)
{
this .V = v;
adj_lis = new LinkedList[V];
for ( int i = 0 ; i < V; i++)
adj_lis[i] = new LinkedList<>();
}
void add_edge( int to, int from, long wt)
{
adj_lis[from].add(
new Edge(from, to, wt));
adj_lis[to].add(
new Edge(to, from, wt));
}
void dfs( int v,
int par,
long sum,
boolean [] visited)
{
val[v] = sum;
visited[v] = true ;
for (Edge e : adj_lis[v]) {
if (!visited[e.to])
dfs(e.to,
v,
sum + e.wt,
visited);
}
}
public static void main(String a[])
{
int v = 6 ;
Graph obj = new Graph(v);
val = new long [v];
boolean [] visited
= new boolean [v];
int sum = 0 ;
int from[] = { 2 , 3 , 5 , 6 , 4 };
int to[] = { 1 , 1 , 2 , 2 , 1 };
int wt[] = { 1 , 4 , 2 , 50 , 5 };
for ( int i = 0 ; i < v - 1 ; i++) {
sum += 2 * wt[i];
obj.add_edge(to[i] - 1 ,
from[i] - 1 ,
wt[i]);
}
obj.dfs( 0 , - 1 , 0 , visited);
long large = Integer.MIN_VALUE;
for ( int i = 1 ; i < val.length;
i++)
if (val[i] > large)
large = val[i];
System.out.println(sum - large);
}
}
|
C#
using System;
using System.Collections.Generic;
class Graph
{
public class Edge
{
public int from ;
public int to;
public long wt;
public Edge( int a, int b, long w)
{
from = a;
to = b;
wt = w;
}
}
public static List<Edge>[] adj_lis;
public static int V;
public static long []val;
public Graph( int v)
{
V = v;
adj_lis = new List<Edge>[V];
for ( int i = 0; i < V; i++)
adj_lis[i] = new List<Edge>();
}
void add_edge( int to, int from , long wt)
{
adj_lis[ from ].Add(
new Edge( from , to, wt));
adj_lis[to].Add(
new Edge(to, from , wt));
}
void dfs( int v,
int par,
long sum,
bool [] visited)
{
val[v] = sum;
visited[v] = true ;
foreach (Edge e in adj_lis[v])
{
if (!visited[e.to])
dfs(e.to, v,
sum + e.wt, visited);
}
}
public static void Main(String []a)
{
int v = 6;
Graph obj = new Graph(v);
val = new long [v];
bool []visited = new bool [v];
int sum = 0;
int [] from = { 2, 3, 5, 6, 4 };
int []to = { 1, 1, 2, 2, 1 };
int []wt = { 1, 4, 2, 50, 5 };
for ( int i = 0; i < v - 1; i++)
{
sum += 2 * wt[i];
obj.add_edge(to[i] - 1,
from [i] - 1, wt[i]);
}
obj.dfs(0, -1, 0, visited);
long large = int .MinValue;
for ( int i = 1; i < val.Length;
i++)
if (val[i] > large)
large = val[i];
Console.WriteLine(sum - large);
}
}
|
Javascript
<script>
class Edge
{
constructor(a, b, w)
{
this .from = a;
this .to = b;
this .wt = w;
}
}
var adj_lis = [];
var V =0;
var val =[];
function Graph(v)
{
V = v;
adj_lis = Array.from(Array(V), ()=>Array());
}
function add_edge(to, from, wt)
{
adj_lis[from].push(
new Edge(from, to, wt));
adj_lis[to].push(
new Edge(to, from, wt));
}
function dfs(v, par, sum, visited)
{
val[v] = sum;
visited[v] = true ;
for ( var e of adj_lis[v])
{
if (!visited[e.to])
dfs(e.to, v, sum + e.wt, visited);
}
}
var v = 6;
Graph(v);
val = new Array(v).fill(0);
var visited = Array(v).fill( false );
var sum = 0;
var from = [2, 3, 5, 6, 4];
var to = [1, 1, 2, 2, 1];
var wt = [1, 4, 2, 50, 5];
for ( var i = 0; i < v - 1; i++)
{
sum += 2 * wt[i];
add_edge(to[i] - 1,
from[i] - 1, wt[i]);
}
dfs(0, -1, 0, visited);
var large = -100000;
for ( var i = 1; i < val.length;i++)
if (val[i] > large)
large = val[i];
document.write(sum - large);
</script>
|
Python3
class Edge:
def __init__( self , a, b, w):
self .src = a
self .to = b
self .wt = w
def add_edge(adj_lis, to, src, wt):
adj_lis[src].append(Edge(src, to, wt))
adj_lis[to].append(Edge(to, src, wt))
def dfs(adj_lis, val, v, par, sum , visited):
val[v] = sum
visited[v] = True
for e in adj_lis[v]:
if ( not visited[e.to]):
dfs(adj_lis, val, e.to, v, sum + e.wt, visited)
if __name__ = = '__main__' :
v = 6
adj_lis = [[] for _ in range (v)]
val = [ - 1 ] * v
visited = [ False ] * v
sum = 0
src = [ 2 , 3 , 5 , 6 , 4 ]
to = [ 1 , 1 , 2 , 2 , 1 ]
wt = [ 1 , 4 , 2 , 50 , 5 ]
for i in range (v - 1 ):
sum + = 2 * wt[i]
add_edge(adj_lis, to[i] - 1 ,
src[i] - 1 , wt[i])
dfs(adj_lis, val, 0 , - 1 , 0 , visited)
large = - 1e9
size = len (val)
for i in range ( 1 ,size):
if (val[i] > large):
large = val[i]
print ( sum - large)
|
Time Complexity: O(N).
Auxiliary Space: O(N).
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...