# Maximize difference between pair of nodes in a given rooted tree such that one node is ancestor of another

Given a Generic Tree consisting of** N** nodes valued from **0** to **(N – 1)** where **P[i] ^{th }**in the array

**P[]**denotes

**i**nodes parent

^{th}**(1-based indexing)**. Each

**i**node has a weight attached to it, given in the array

^{th}**W[]**. The task is to find a pair of nodes

**(u, v),**such that

**u**is an ancestor of

**v**, and

**W**is maximized.

_{u}– W_{v}**Note:** In the array **P[]**, **-1** denotes the root node. If there’s a single node, then print **-1**.

**Examples:**

Input:N = 4, W[] = {5, 10, 6, 12}, P[] = {2, -1, 4, 2}Output:6Explanation:The tree with weight will be:

Here, 4

^{th}node having weight 12 and 3^{rd}node having weight 6, the difference will be (12 – 6) = 6.

Input:N = 1, W = { 30 }, P = { -1 }Output:-1

**Approach:** The given problem can be solved by using the Breadth-First Search on the **N-ary Tree** to mark the ancestor number for the given tree **P[]**, and then using DFS Traversal and find the maximum difference **maxDiff**, by considering every node as an ancestor with its corresponding nodes having less number ancestor value. Follow the steps below to solve the problem:

- Define a function
**dfs(int src, int val, vector<int> & W)**and perform the following tasks:- Set the value of
**visited[src]**as**true**. - Iterate over the range
**[0, size)**where**size**is the size of the row**tree[cur]**using the variable**neighbor**and performs the following tasks:- If
**visited[neighbor]**is**false**and**ancestor[neighbor]**is greater than**ancestor[src]**then set the value of**maxDiff**as the maximum of**maxDiff**or**val – W[neighbor-1]**. - Call the function
**dfs(neighbor, val, W)**.

- If

- Set the value of
- Define a function
**bfs(int src, int N)**and perform the following tasks:- Assign the vector
**visited[N + 1]**with values**false.** - Initialize a queue
**q[]**. - Set the value of
**ancestorNum[src]**as**0**and**visited[src]**as**true**. - Enqueue the value
**src**into the queue**q[]**. - Traverse in a while loop till queue
**q[]**is not empty and perform the following tasks:- Initialize the variable
**cur**as the front element of the queue**q[]**and dequeue from the queue**q[].** - Iterate over the range
**[0, size)**where**size**is the size of the row**tree[cur]**using the variable**neighbor**and if**visited[neighbor]**is**false**then set it as**true**and enqueue it into the queue**q[]**and set the value of**ancestor[neighbor]**as**(ancestor[cur] + 1)**.

- Initialize the variable

- Assign the vector
- Initialize the vectors
**tree[][], visited[]**and**ancestorNum[]**. - Initialize the variable
**maxDiff**as**INT_MIN**to store the answer. - Resize the vector
**tree[][]**to size**(N + 1)**. - Assign vectors
**visited[N + 1]**with value**false**and**ancestorNum[N+1]**with value**0**. - Initialize the variable
**src**. - Iterate over the range
**[0, N)**using the variable**i**and if**P[**I**]**is**-1**, then set the value of**src**as**i**. Otherwise, push the value**P[**I**]**in the row**i+1**and value**i + 1**in the row**P[**I**]**into the vector**tree[][]**. - Call the function
**bfs(src, N+1)**to perform breadth-first search. - Assign vector
**visited[N+1]**with value**false**. - Call the function
**dfs(src, W[src], W)**to perform depth-first search. - Iterate over the range
**[0, N)**using the variable**i**and perform the following steps:- If
**i**equals**src**, then continue. Otherwise, assign vector**visited[N+1]**with value**false**. - Call the function
**dfs(i+1, W[i], W)**.

- If
- After performing the above steps, print the value of
**maxDiff**as the answer.

Below is the implementation of the above approach:

## C++

`// C++ program for the above approach` `#include <bits/stdc++.h>` `using` `namespace` `std;` `vector<vector<` `int` `> > tree;` `vector<` `bool` `> visited;` `vector<` `int` `> ancestorNum;` `// Stores the maximum difference` `int` `maxDiff = INT_MIN;` `// DFS traversal for source node as src` `void` `dfs(` `int` `src, ` `int` `val, vector<` `int` `>& W)` `{` ` ` `// Mark src node as visited` ` ` `visited[src] = ` `true` `;` ` ` `// Traverse the tree` ` ` `for` `(` `auto` `neighbour : tree[src]) {` ` ` `// Check neighbour node is not` ` ` `// visited and ancestorNum should` ` ` `// be greater than the src node` ` ` `if` `(!visited[neighbour]` ` ` `&& (ancestorNum[neighbour]` ` ` `> ancestorNum[src])) {` ` ` `// Update the maxDiff` ` ` `maxDiff = max(` ` ` `val - W[neighbour - 1],` ` ` `maxDiff);` ` ` `// Recurrence call for dfs` ` ` `dfs(neighbour, val, W);` ` ` `}` ` ` `}` `}` `// BFS traversal for source node as src` `void` `bfs(` `int` `src, ` `int` `N)` `{` ` ` `// Initially mark all node as` ` ` `// not visited` ` ` `visited.assign(N, ` `false` `);` ` ` `// Stores the nodes` ` ` `queue<` `int` `> q;` ` ` `// Initially for src node mark` ` ` `// ancestorNum as 0` ` ` `ancestorNum[src] = 0;` ` ` `// Mark src as visited` ` ` `visited[src] = ` `true` `;` ` ` `// Push src node into the q` ` ` `q.push(src);` ` ` `// Traverse the queue q` ` ` `while` `(!q.empty()) {` ` ` `// Pop front element of the q` ` ` `int` `cur = q.front();` ` ` `q.pop();` ` ` `// Traverse the tree` ` ` `for` `(` `auto` `neighbour : tree[cur]) {` ` ` `// Check neighbour node is` ` ` `// already not visited` ` ` `if` `(!visited[neighbour]) {` ` ` `// Mark the neighbour` ` ` `// node as visited` ` ` `visited[neighbour] = ` `true` `;` ` ` `// Push the neighbour` ` ` `// node into the q` ` ` `q.push(neighbour);` ` ` `// Update the neighbour` ` ` `// node ancestorNum` ` ` `ancestorNum[neighbour]` ` ` `= ancestorNum[cur] + 1;` ` ` `}` ` ` `}` ` ` `}` `}` `// Function to find the the maximized` `// difference between two pair of nodes` `// in rooted tree such that one node` `// is ancestor of another node` `void` `maximumDiff(vector<` `int` `> W,` ` ` `vector<` `int` `> P, ` `int` `N)` `{` ` ` `if` `(N == 1) {` ` ` `cout << ` `"-1\n"` `;` ` ` `return` `;` ` ` `}` ` ` `// Resize the tree` ` ` `tree.resize(N + 1);` ` ` `// Mark all the nodes as not visited` ` ` `visited.assign(N + 1, ` `false` `);` ` ` `// Assign all the node values` ` ` `// for ancestorNum to 0` ` ` `ancestorNum.assign(N + 1, 0);` ` ` `// Stores the source node to traverse` ` ` `int` `src;` ` ` `for` `(` `int` `i = 0; i < N; i++) {` ` ` `// Check P[i] is -1` ` ` `if` `(P[i] == -1)` ` ` `// Update the source node src` ` ` `src = i;` ` ` `else` `{` ` ` `// Store the tree values` ` ` `tree[i + 1].push_back(P[i]);` ` ` `tree[P[i]].push_back(i + 1);` ` ` `}` ` ` `}` ` ` `// BFS from the source node src` ` ` `bfs(src, N + 1);` ` ` `// Mark all the nodes as not visited` ` ` `visited.assign(N + 1, ` `false` `);` ` ` `// DFS Call for source node src` ` ` `dfs(src, W[src], W);` ` ` `// For every node call dfs function` ` ` `for` `(` `int` `i = 0; i < N; i++) {` ` ` `// Check i is root node` ` ` `if` `(i == src)` ` ` `continue` `;` ` ` `// Mark all the nodes as` ` ` `// not visited` ` ` `visited.assign(N + 1, ` `false` `);` ` ` `// DFS Call for source` ` ` `// node as i+1` ` ` `dfs(i + 1, W[i], W);` ` ` `}` ` ` `// Print the maxDiff` ` ` `cout << maxDiff << endl;` `}` `// Driver Code` `int` `main()` `{` ` ` `vector<` `int` `> W = { 5, 10, 6, 12 };` ` ` `vector<` `int` `> P = { 2, -1, 4, 2 };` ` ` `int` `N = P.size();` ` ` `maximumDiff(W, P, N);` ` ` `return` `0;` `}` |

## Python3

`# Python 3 program for the above approach` `tree ` `=` `[]` `visited ` `=` `[]` `ancestorNum ` `=` `[]` `import` `sys` `# Stores the maximum difference` `maxDiff ` `=` `-` `sys.maxsize ` `-` `1` `# DFS traversal for source node as src` `def` `dfs(src, val, W):` ` ` `global` `ancestorNum` ` ` `global` `visited` ` ` `global` `tree` ` ` `global` `maxDiff` ` ` `# Mark src node as visited` ` ` `visited[src] ` `=` `True` ` ` `# Traverse the tree` ` ` `for` `neighbour ` `in` `tree[src]:` ` ` `# Check neighbour node is not` ` ` `# visited and ancestorNum should` ` ` `# be greater than the src node` ` ` `if` `(visited[neighbour] ` `=` `=` `False` `and` `(ancestorNum[neighbour]> ancestorNum[src])):` ` ` `# Update the maxDiff` ` ` `maxDiff ` `=` `max` `(val ` `-` `W[neighbour ` `-` `1` `],maxDiff)` ` ` `# Recurrence call for dfs` ` ` `dfs(neighbour, val, W)` `# BFS traversal for source node as src` `def` `bfs(src,N):` ` ` `global` `ancestorNum` ` ` `global` `visited` ` ` `global` `tree` ` ` `# Initially mark all node as` ` ` `# not visited` ` ` `visited ` `=` `[` `False` `for` `i ` `in` `range` `(N)]` ` ` `# Stores the nodes` ` ` `q ` `=` `[]` ` ` `# Initially for src node mark` ` ` `# ancestorNum as 0` ` ` `ancestorNum[src] ` `=` `0` ` ` `# Mark src as visited` ` ` `visited[src] ` `=` `True` ` ` `# Push src node into the q` ` ` `q.append(src)` ` ` `# Traverse the queue q` ` ` `while` `(` `len` `(q)>` `0` `):` ` ` `# Pop front element of the q` ` ` `cur ` `=` `q[` `0` `]` ` ` `q ` `=` `q[` `1` `:]` ` ` `# Traverse the tree` ` ` `for` `neighbour ` `in` `tree[cur]:` ` ` `# Check neighbour node is` ` ` `# already not visited` ` ` `if` `(visited[neighbour]` `=` `=` `False` `):` ` ` `# Mark the neighbour` ` ` `# node as visited` ` ` `visited[neighbour] ` `=` `True` ` ` `# Push the neighbour` ` ` `# node into the q` ` ` `q.append(neighbour)` ` ` `# Update the neighbour` ` ` `# node ancestorNum` ` ` `ancestorNum[neighbour] ` `=` `ancestorNum[cur] ` `+` `1` `# Function to find the the maximized` `# difference between two pair of nodes` `# in rooted tree such that one node` `# is ancestor of another node` `def` `maximumDiff(W, P, N):` ` ` `global` `ancestorNum` ` ` `global` `visited` ` ` `global` `tree` ` ` `if` `(N ` `=` `=` `1` `):` ` ` `print` `(` `"-1"` `)` ` ` `return` ` ` `# Resize the tree` ` ` `tree ` `=` `[[] ` `for` `i ` `in` `range` `(N` `+` `1` `)]` ` ` `# Mark all the nodes as not visited` ` ` `visited ` `=` `[` `False` `for` `i ` `in` `range` `(N ` `+` `1` `)]` ` ` `# Assign all the node values` ` ` `# for ancestorNum to 0` ` ` `ancestorNum ` `=` `[` `0` `for` `i ` `in` `range` `(N ` `+` `1` `)]` ` ` `# Stores the source node to traverse` ` ` `src ` `=` `0` ` ` `for` `i ` `in` `range` `(N):` ` ` `# Check P[i] is -1` ` ` `if` `(P[i] ` `=` `=` `-` `1` `):` ` ` `# Update the source node src` ` ` `src ` `=` `i` ` ` `else` `:` ` ` `# Store the tree values` ` ` `tree[i ` `+` `1` `].append(P[i])` ` ` `tree[P[i]].append(i ` `+` `1` `)` ` ` `# BFS from the source node src` ` ` `bfs(src, N ` `+` `1` `)` ` ` `# Mark all the nodes as not visited` ` ` `visited ` `=` `[` `False` `for` `i ` `in` `range` `(N` `+` `1` `)]` ` ` `# DFS Call for source node src` ` ` `dfs(src, W[src], W)` ` ` `# For every node call dfs function` ` ` `for` `i ` `in` `range` `(N):` ` ` `# Check i is root node` ` ` `if` `(i ` `=` `=` `src):` ` ` `continue` ` ` `# Mark all the nodes as` ` ` `# not visited` ` ` `visited ` `=` `[` `False` `for` `i ` `in` `range` `(N` `+` `1` `)]` ` ` `# DFS Call for source` ` ` `# node as i+1` ` ` `dfs(i ` `+` `1` `, W[i], W)` ` ` `# Print the maxDiff` ` ` `print` `(maxDiff)` `# Driver Code` `if` `__name__ ` `=` `=` `'__main__'` `:` ` ` `W ` `=` `[` `5` `, ` `10` `, ` `6` `, ` `12` `]` ` ` `P ` `=` `[` `2` `, ` `-` `1` `, ` `4` `, ` `2` `]` ` ` `N ` `=` `len` `(P)` ` ` `maximumDiff(W, P, N)` ` ` ` ` `# This code is contributed by SURENDRA_GANGWAR.` |

**Output:**

6

**Time Complexity:** O(N^{2})**Auxiliary Space:** O(N)