// C# implementation to find the // maximum weighted edge in the simple // path between two nodes in N-ary Tree using System; using System.Collections.Generic; class GFG { static int N = 100005; // Depths of Nodes static int[] level = new int[N]; static int LG = 20; // Parent at every 2^i level static int[,] dp = new int[LG, N]; // Maximum node at every 2^i level static int[,] mx = new int[LG, N]; // Graph that stores destinations // and its weight static List<List<Tuple<int,int>>> v = new List<List<Tuple<int,int>>>(); static int n = 0; // Function to traverse the // nodes using the Depth-First // Search Traversal static void dfs_lca(int a, int par, int lev) { dp[0,a] = par; level[a] = lev; for(int i = 0; i < v[a].Count; i++) { // Condition to check // if its equal to its // parent then skip if (v[a][i].Item1 == par) continue; mx[0,v[a][i].Item1] = v[a][i].Item2; // DFS Recursive Call dfs_lca(v[a][i].Item1, a, lev + 1); } } // Function to find the ancestor static void find_ancestor() { // Loop to set every 2^i distance for(int i = 1; i < 16; i++) { // Loop to calculate for // each node in the N-ary tree for(int j = 1; j < n + 1; j++) { dp[i,j] = dp[i - 1,dp[i - 1,j]]; // Storing maximum edge mx[i,j] = Math.Max(mx[i - 1,j], mx[i - 1,dp[i - 1,j]]); } } } static int getMax(int a, int b) { // Swapping if node a is at more depth // than node b because we will // always take at more depth if (level[b] < level[a]) { int temp = a; a = b; b = temp; } int ans = 0; // Difference between the // depth of the two given // nodes int diff = level[b] - level[a]; while (diff > 0) { int log = (int)(Math.Log(diff) / Math.Log(2)); ans = Math.Max(ans, mx[log,b]); // Changing Node B to its // parent at 2 ^ i distance b = dp[log,b]; // Subtracting distance by 2^i diff -= (1 << log); } // Take both a, b to its // lca and find maximum while (a != b) { int i = (int)(Math.Log(level[a]) / Math.Log(2)); // Loop to find the maximum 2^ith // parent the is different // for both a and b while (i > 0 && dp[i,a] == dp[i,b]) { i-=1; } // Updating ans ans = Math.Max(ans, mx[i,a]); ans = Math.Max(ans, mx[i,b]); // Changing value to // its parent a = dp[i,a]; b = dp[i,b]; } return ans; } // Function to compute the Least // common Ancestor static void compute_lca() { dfs_lca(1, 0, 0); find_ancestor(); } static void Main() { for(int i = 0; i < LG; i++) { for(int j = 0; j < N; j++) { dp[i,j] = 0; mx[i,j] = 0; } } for(int i = 0; i < N; i++) { v.Add(new List<Tuple<int,int>>()); } // Undirected tree v[1].Add(new Tuple<int,int>(2, 2)); v[2].Add(new Tuple<int,int>(1, 2)); v[1].Add(new Tuple<int,int>(3, 5)); v[3].Add(new Tuple<int,int>(1, 5)); v[3].Add(new Tuple<int,int>(4, 3)); v[4].Add(new Tuple<int,int>(3, 4)); v[3].Add(new Tuple<int,int>(5, 1)); v[5].Add(new Tuple<int,int>(3, 1)); // Computing LCA compute_lca(); int[,] queries = { { 3, 5 }, { 2, 3 }, { 2, 4 } }; int q = 3; for (int i = 0; i < q; i++) { int max_edge = getMax(queries[i,0], queries[i,1]); Console.WriteLine(max_edge); } } } // This code is contributed by divyesh072019.