# Maximum weighted edge in path between two nodes in an N-ary tree using binary lifting

Given an N-ary tree with weighted edge and **Q** queries where each query contains two nodes of the tree. The task is to find the maximum weighted edge in the simple path between these two nodes.**Examples:**

**Naive Approach:** A simple solution is to traverse the whole tree for each query and find the path between the two nodes.**Efficient Approach:** The idea is to use binary lifting to pre-compute the maximum weighted edge from every node to every other node at distance of some

. We will store the maximum weighted edge till

level.

and

where

- j is the node and
- i is the distance of

- dp[i][j] stores the parent of j at

- distance if present, else it will store 0
- mx[i][j] stores the maximum edge from node j to the parent of this node at

- distance.

We’ll do a depth-first search to find all the parents at

distance and their weight and then precompute parents and maximum edges at every

distance.

Below is the implementation of the above approach:

## C++

`// C++ implementation to find the` `// maximum weighted edge in the simple` `// path between two nodes in N-ary Tree` `#include <bits/stdc++.h>` `using` `namespace` `std;` `const` `int` `N = 100005;` `// Depths of Nodes` `vector<` `int` `> level(N);` `const` `int` `LG = 20;` `// Parent at every 2^i level` `vector<vector<` `int` `> > dp(LG, vector<` `int` `>(N));` `// Maximum node at every 2^i level` `vector<vector<` `int` `> > mx(LG, vector<` `int` `>(N));` `// Graph that stores destinations` `// and its weight` `vector<vector<pair<` `int` `, ` `int` `> > > v(N);` `int` `n;` `// Function to traverse the nodes` `// using the Depth-First Search Traversal` `void` `dfs_lca(` `int` `a, ` `int` `par, ` `int` `lev)` `{` ` ` `dp[0][a] = par;` ` ` `level[a] = lev;` ` ` `for` `(` `auto` `i : v[a]) {` ` ` `// Condition to check if its` ` ` `// equal to its parent then skip` ` ` `if` `(i.first == par)` ` ` `continue` `;` ` ` `mx[0][i.first] = i.second;` ` ` `// DFS Recursive Call` ` ` `dfs_lca(i.first, a, lev + 1);` ` ` `}` `}` `// Function to find the ansector` `void` `find_ancestor()` `{` ` ` `// Loop to set every 2^i distance` ` ` `for` `(` `int` `i = 1; i < LG; i++) {` ` ` `// Loop to calculate for` ` ` `// each node in the N-ary tree` ` ` `for` `(` `int` `j = 1; j <= n; j++) {` ` ` `dp[i][j]` ` ` `= dp[i - 1][dp[i - 1][j]];` ` ` `// Storing maximum edge` ` ` `mx[i][j]` ` ` `= max(mx[i - 1][j],` ` ` `mx[i - 1][dp[i - 1][j]]);` ` ` `}` ` ` `}` `}` `int` `getMax(` `int` `a, ` `int` `b)` `{` ` ` `// Swaping if node a is at more depth` ` ` `// than node b because we will` ` ` `// always take at more depth` ` ` `if` `(level[b] < level[a])` ` ` `swap(a, b);` ` ` `int` `ans = 0;` ` ` `// Difference between the depth of` ` ` `// the two given nodes` ` ` `int` `diff = level[b] - level[a];` ` ` `while` `(diff > 0) {` ` ` `int` `log` `= log2(diff);` ` ` `ans = 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 = log2(level[a]);` ` ` `// 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--;` ` ` `// Updating ans` ` ` `ans = max(ans, mx[i][a]);` ` ` `ans = 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 Ansector` `void` `compute_lca()` `{` ` ` `dfs_lca(1, 0, 0);` ` ` `find_ancestor();` `}` `// Driver Code` `int` `main()` `{` ` ` `// Undirected tree` ` ` `n = 5;` ` ` `v[1].push_back(make_pair(2, 2));` ` ` `v[2].push_back(make_pair(1, 2));` ` ` `v[1].push_back(make_pair(3, 5));` ` ` `v[3].push_back(make_pair(1, 5));` ` ` `v[3].push_back(make_pair(4, 3));` ` ` `v[4].push_back(make_pair(3, 4));` ` ` `v[3].push_back(make_pair(5, 1));` ` ` `v[5].push_back(make_pair(3, 1));` ` ` `// Computing LCA` ` ` `compute_lca();` ` ` `int` `queries[][2]` ` ` `= { { 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]);` ` ` `cout << max_edge << endl;` ` ` `}` ` ` `return` `0;` `}` |

## Python3

`# Python3 implementation to` `# find the maximum weighted` `# edge in the simple path` `# between two nodes in N-ary Tree` `import` `math` `N ` `=` `100005` `;` ` ` `# Depths of Nodes` `level ` `=` `[` `0` `for` `i ` `in` `range` `(N)]` `LG ` `=` `20` `;` ` ` `# Parent at every 2^i level` `dp ` `=` `[[` `0` `for` `j ` `in` `range` `(N)]` ` ` `for` `i ` `in` `range` `(LG)]` ` ` `# Maximum node at every 2^i level` `mx ` `=` `[[` `0` `for` `j ` `in` `range` `(N)]` ` ` `for` `i ` `in` `range` `(LG)]` ` ` `# Graph that stores destinations` `# and its weight` `v ` `=` `[[] ` `for` `i ` `in` `range` `(N)]` `n ` `=` `0` ` ` `# Function to traverse the` `# nodes using the Depth-First` `# Search Traversal` `def` `dfs_lca(a, par, lev):` ` ` `dp[` `0` `][a] ` `=` `par;` ` ` `level[a] ` `=` `lev;` ` ` ` ` `for` `i ` `in` `v[a]:` ` ` ` ` `# Condition to check` ` ` `# if its equal to its` ` ` `# parent then skip` ` ` `if` `(i[` `0` `] ` `=` `=` `par):` ` ` `continue` `;` ` ` `mx[` `0` `][i[` `0` `]] ` `=` `i[` `1` `];` ` ` ` ` `# DFS Recursive Call` ` ` `dfs_lca(i[` `0` `], a, lev ` `+` `1` `);` `# Function to find the ansector` `def` `find_ancestor():` ` ` ` ` `# Loop to set every 2^i distance` ` ` `for` `i ` `in` `range` `(` `1` `, ` `16` `):` ` ` ` ` `# Loop to calculate for` ` ` `# each node in the N-ary tree` ` ` `for` `j ` `in` `range` `(` `1` `, n ` `+` `1` `):` ` ` ` ` `dp[i][j] ` `=` `dp[i ` `-` `1` `][dp[i ` `-` `1` `][j]];` ` ` ` ` `# Storing maximum edge` ` ` `mx[i][j] ` `=` `max` `(mx[i ` `-` `1` `][j],` ` ` `mx[i ` `-` `1` `][dp[i ` `-` `1` `][j]]);` `def` `getMax(a, b):` ` ` `# Swaping if node a is at more depth` ` ` `# than node b because we will` ` ` `# always take at more depth` ` ` `if` `(level[b] < level[a]):` ` ` `a, b ` `=` `b, a` ` ` ` ` `ans ` `=` `0` `;` ` ` ` ` `# Difference between the` ` ` `# depth of the two given` ` ` `# nodes` ` ` `diff ` `=` `level[b] ` `-` `level[a];` ` ` ` ` `while` `(diff > ` `0` `):` ` ` `log ` `=` `int` `(math.log2(diff));` ` ` `ans ` `=` `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):` ` ` `i ` `=` `int` `(math.log2(level[a]));` ` ` ` ` `# Loop to find the maximum 2^ith` ` ` `# parent the is different` ` ` `# for both a and b` ` ` `while` `(i > ` `0` `and` ` ` `dp[i][a] ` `=` `=` `dp[i][b]):` ` ` `i` `-` `=` `1` ` ` ` ` `# Updating ans` ` ` `ans ` `=` `max` `(ans, mx[i][a]);` ` ` `ans ` `=` `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 Ansector` `def` `compute_lca():` ` ` ` ` `dfs_lca(` `1` `, ` `0` `, ` `0` `);` ` ` `find_ancestor();` `# Driver code` `if` `__name__` `=` `=` `"__main__"` `:` ` ` ` ` `# Undirected tree` ` ` `n ` `=` `5` `;` ` ` `v[` `1` `].append([` `2` `, ` `2` `]);` ` ` `v[` `2` `].append([` `1` `, ` `2` `]);` ` ` `v[` `1` `].append([` `3` `, ` `5` `]);` ` ` `v[` `3` `].append([` `1` `, ` `5` `]);` ` ` `v[` `3` `].append([` `4` `, ` `3` `]);` ` ` `v[` `4` `].append([` `3` `, ` `4` `]);` ` ` `v[` `3` `].append([` `5` `, ` `1` `]);` ` ` `v[` `5` `].append([` `3` `, ` `1` `]);` ` ` ` ` `# Computing LCA` ` ` `compute_lca();` ` ` ` ` `queries` `=` `[[` `3` `, ` `5` `], [` `2` `, ` `3` `], [` `2` `,` `4` `]]` ` ` `q ` `=` `3` `;` ` ` ` ` `for` `i ` `in` `range` `(q):` ` ` `max_edge ` `=` `getMax(queries[i][` `0` `],` ` ` `queries[i][` `1` `]);` ` ` `print` `(max_edge)` ` ` `# This code is contributed by Rutvik_56` |

**Output:**

1 5 5

**Time Complexity:**