Минимальное расстояние для посещения всех узлов неориентированного взвешенного дерева
Дано взвешенное дерево с N узлами, начиная с 1 до N. Расстояние между любыми двумя узлами определяется весом ребра. Узел 1 является источником, задача - посетить все узлы дерева с минимальным пройденным расстоянием.
Примеры:
Input:
u[] = {1, 1, 2, 2, 1}
v[] = {2, 3, 5, 6, 4}
w[] = {1, 4, 2, 50, 5}
Output: 73Input:
u[] = {1, 2}
v[] = {2, 3}
w[] = {3, 1}
Output: 4
Подход: Предположим, что имеется n листов l 1 , l 2 , l 3 , ……, l n, а стоимость пути от корня до каждого листа равна c 1 , c 2 , c 3 , ……, c n .
Для перехода от l 1 к l 2 некоторые ребра будут посещены дважды (до LCA l 1 и l 2 все ребра будут посещены дважды), для l 2 - l 3 будут посещены некоторые из ребер ( до LCA l 2 и l 3 все ребра будут посещены дважды) дважды, и аналогично каждое ребро дерева будет посещено дважды (наблюдение).
Чтобы минимизировать затраты на перемещение, следует избегать пути максимальной стоимости от корня до некоторого листа.
Следовательно, стоимость = ( c 1 + c 2 + c 3 + …… + c n ) - max ( c 1 , c 2 , c 3 , ……, c n )
минимальная стоимость = (2 * сумма веса ребер) - max ( c 1 , c 2 , c 3 , ……, c n )
DFS можно использовать с некоторыми модификациями, чтобы найти наибольшее расстояние.
Below is the implementation of the above approach:
C++
// C++ implementation of above approach #include <bits/stdc++.h> using namespace std; class Edge{ public : // from - The source of an edge // to - destination of an edge // wt - distance between two nodes int from; int to; long wt; Edge( int a, int b, long w) { from = a; to = b; wt = w; } }; // Method to add an edge between two nodes 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)); } // DFS method to find distance // between node 1 to other nodes 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); } } // Driver code int main() { // Number of nodes // V - Total number of // nodes in a tree int v = 6; // adj_lis - It is used to // make the adjacency list of a tree vector<vector<Edge>> adj_lis(v); // val - This array stores the // distance from node 1 to node "n" long val[v]; bool visited[v]; int sum = 0; // Edge from a node to another // node with some weight 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; // Loop to find largest // distance in a val. int size = sizeof (val) / sizeof ( long ); for ( int i = 1; i < size; i++) if (val[i] > large) large = val[i]; cout << (sum - large); } // This code is contributed by sanjeev2552 |
Java
// Java implementation of the approach import java.util.LinkedList; import java.util.Scanner; class Graph { class Edge { // from - The source of an edge // to - destination of an edge // wt - distance between two nodes int from; int to; long wt; Edge( int a, int b, long w) { from = a; to = b; wt = w; } } // adj_lis - It is used to // make the adjacency list of a tree // V - Total number of nodes in a tree // val - This array stores the // distance from node 1 to node "n" 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<>(); } // Method to add an edge between two nodes 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)); } // DFS method to find distance // between node 1 to other nodes 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); } } // Driver code public static void main(String a[]) { // Number of nodes int v = 6 ; Graph obj = new Graph(v); val = new long [v]; boolean [] visited = new boolean [v]; int sum = 0 ; // Edge from a node to another // node with some weight 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; // Loop to find largest // distance in a val. for ( int i = 1 ; i < val.length; i++) if (val[i] > large) large = val[i]; System.out.println(sum - large); } } |
C#
// C# implementation of above approach using System; using System.Collections.Generic; class Graph { public class Edge { // from - The source of an edge // to - destination of an edge // wt - distance between two nodes public int from ; public int to; public long wt; public Edge( int a, int b, long w) { from = a; to = b; wt = w; } } // adj_lis - It is used to // make the adjacency list of a tree // V - Total number of nodes in a tree // val - This array stores the // distance from node 1 to node "n" 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>(); } // Method to add an edge between two nodes 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)); } // DFS method to find distance // between node 1 to other nodes 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); } } // Driver code public static void Main(String []a) { // Number of nodes int v = 6; Graph obj = new Graph(v); val = new long [v]; bool []visited = new bool [v]; int sum = 0; // Edge from a node to another // node with some weight 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; // Loop to find largest // distance in a val. for ( int i = 1; i < val.Length; i++) if (val[i] > large) large = val[i]; Console.WriteLine(sum - large); } } // This code is contributed by Princi Singh |
73
Вниманию читателя! Не прекращайте учиться сейчас. Освойте все важные концепции DSA с помощью самостоятельного курса DSA по приемлемой для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .
Если вы хотите посещать живые занятия с отраслевыми экспертами, пожалуйста, обращайтесь к Geeks Classes Live и Geeks Classes Live USA.