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

• Last Updated : 21 Sep, 2021

Given a Generic Tree consisting of N nodes valued from 0 to (N – 1) where P[i]th in the array P[] denotes ith nodes parent(1-based indexing). Each ith node has a weight attached to it, given in the array W[]. The task is to find a pair of nodes (u, v), such that u is an ancestor of v, and Wu – Wv is maximized.

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: 6
Explanation: The tree with weight will be: Here, 4th node having weight 12 and 3rd 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:

Below is the implementation of the above approach:

C++

 // C++ program for the above approach #include using namespace std;   vector > tree; vector visited; vector ancestorNum;   // Stores the maximum difference int maxDiff = INT_MIN;   // DFS traversal for source node as src void dfs(int src, int val, vector& 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 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 W,                  vector 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 W = { 5, 10, 6, 12 };     vector 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         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(N2)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :