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:
- 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).
- Define a function bfs(int src, int N) and perform the following tasks:
- 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:
- After performing the above steps, print the value of maxDiff as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector<vector< int > > tree;
vector< bool > visited;
vector< int > ancestorNum;
int maxDiff = INT_MIN;
void dfs( int src, int val, vector< int >& W)
{
visited[src] = true ;
for ( auto neighbour : tree[src]) {
if (!visited[neighbour]
&& (ancestorNum[neighbour]
> ancestorNum[src])) {
maxDiff = max(
val - W[neighbour - 1],
maxDiff);
dfs(neighbour, val, W);
}
}
}
void bfs( int src, int N)
{
visited.assign(N, false );
queue< int > q;
ancestorNum[src] = 0;
visited[src] = true ;
q.push(src);
while (!q.empty()) {
int cur = q.front();
q.pop();
for ( auto neighbour : tree[cur]) {
if (!visited[neighbour]) {
visited[neighbour] = true ;
q.push(neighbour);
ancestorNum[neighbour]
= ancestorNum[cur] + 1;
}
}
}
}
void maximumDiff(vector< int > W,
vector< int > P, int N)
{
if (N == 1) {
cout << "-1\n" ;
return ;
}
tree.resize(N + 1);
visited.assign(N + 1, false );
ancestorNum.assign(N + 1, 0);
int src;
for ( int i = 0; i < N; i++) {
if (P[i] == -1)
src = i;
else {
tree[i + 1].push_back(P[i]);
tree[P[i]].push_back(i + 1);
}
}
bfs(src, N + 1);
visited.assign(N + 1, false );
dfs(src, W[src], W);
for ( int i = 0; i < N; i++) {
if (i == src)
continue ;
visited.assign(N + 1, false );
dfs(i + 1, W[i], W);
}
cout << maxDiff << endl;
}
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;
}
|
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
private static ArrayList<ArrayList<Integer> > tree;
private static boolean [] visited;
private static int [] ancestorNum;
private static int maxDiff = Integer.MIN_VALUE;
private static void dfs( int src, int val, int [] W)
{
visited[src] = true ;
for ( int neighbour : tree.get(src)) {
if (!visited[neighbour]
&& ancestorNum[neighbour]
> ancestorNum[src]) {
maxDiff = Math.max(val - W[neighbour - 1 ],
maxDiff);
dfs(neighbour, val, W);
}
}
}
private static void bfs( int src, int N)
{
visited = new boolean [N];
Arrays.fill(visited, false );
Queue<Integer> q = new LinkedList<>();
ancestorNum[src] = 0 ;
visited[src] = true ;
q.offer(src);
while (!q.isEmpty()) {
int cur = q.poll();
for ( int neighbour : tree.get(cur)) {
if (!visited[neighbour]) {
visited[neighbour] = true ;
q.offer(neighbour);
ancestorNum[neighbour]
= ancestorNum[cur] + 1 ;
}
}
}
}
private static void maximumDiff( int [] W, int [] P, int N)
{
if (N == 1 ) {
System.out.println( "-1" );
return ;
}
tree = new ArrayList<>();
for ( int i = 0 ; i <= N; i++)
tree.add( new ArrayList<>());
int src = 0 ;
for ( int i = 0 ; i < N; i++) {
if (P[i] == - 1 ) {
src = i;
}
else {
tree.get(i + 1 ).add(P[i]);
tree.get(P[i]).add(i + 1 );
}
}
ancestorNum = new int [N + 1 ];
bfs(src, N + 1 );
Arrays.fill(visited, false );
dfs(src, W[src], W);
for ( int i = 0 ; i < N; i++) {
if (i == src)
continue ;
Arrays.fill(visited, false );
dfs(i + 1 , W[i], W);
}
System.out.println(maxDiff);
}
public static void main(String[] args)
{
int [] W = { 5 , 10 , 6 , 12 };
int [] P = { 2 , - 1 , 4 , 2 };
int N = P.length;
maximumDiff(W, P, N);
}
}
|
Python3
tree = []
visited = []
ancestorNum = []
import sys
maxDiff = - sys.maxsize - 1
def dfs(src, val, W):
global ancestorNum
global visited
global tree
global maxDiff
visited[src] = True
for neighbour in tree[src]:
if (visited[neighbour] = = False and (ancestorNum[neighbour]> ancestorNum[src])):
maxDiff = max (val - W[neighbour - 1 ],maxDiff)
dfs(neighbour, val, W)
def bfs(src,N):
global ancestorNum
global visited
global tree
visited = [ False for i in range (N)]
q = []
ancestorNum[src] = 0
visited[src] = True
q.append(src)
while ( len (q)> 0 ):
cur = q[ 0 ]
q = q[ 1 :]
for neighbour in tree[cur]:
if (visited[neighbour] = = False ):
visited[neighbour] = True
q.append(neighbour)
ancestorNum[neighbour] = ancestorNum[cur] + 1
def maximumDiff(W, P, N):
global ancestorNum
global visited
global tree
if (N = = 1 ):
print ( "-1" )
return
tree = [[] for i in range (N + 1 )]
visited = [ False for i in range (N + 1 )]
ancestorNum = [ 0 for i in range (N + 1 )]
src = 0
for i in range (N):
if (P[i] = = - 1 ):
src = i
else :
tree[i + 1 ].append(P[i])
tree[P[i]].append(i + 1 )
bfs(src, N + 1 )
visited = [ False for i in range (N + 1 )]
dfs(src, W[src], W)
for i in range (N):
if (i = = src):
continue
visited = [ False for i in range (N + 1 )]
dfs(i + 1 , W[i], W)
print (maxDiff)
if __name__ = = '__main__' :
W = [ 5 , 10 , 6 , 12 ]
P = [ 2 , - 1 , 4 , 2 ]
N = len (P)
maximumDiff(W, P, N)
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int maxDiff = int .MinValue;
static List<List< int >> tree = new List<List< int >>();
static bool [] visited;
static int [] ancestorNum;
static void DFS( int src, int val, int [] W)
{
visited[src] = true ;
foreach ( int neighbour in tree[src])
{
if (!visited[neighbour] && ancestorNum[neighbour] > ancestorNum[src])
{
maxDiff = Math.Max(val - W[neighbour - 1], maxDiff);
DFS(neighbour, val, W);
}
}
}
static void BFS( int src, int N)
{
visited = new bool [N];
Queue< int > q = new Queue< int >();
ancestorNum = new int [N];
ancestorNum[src] = 0;
visited[src] = true ;
q.Enqueue(src);
while (q.Count > 0)
{
int cur = q.Dequeue();
foreach ( int neighbour in tree[cur])
{
if (!visited[neighbour])
{
visited[neighbour] = true ;
q.Enqueue(neighbour);
ancestorNum[neighbour] = ancestorNum[cur] + 1;
}
}
}
}
static void MaximumDiff( int [] W, int [] P, int N)
{
if (N == 1)
{
Console.WriteLine( "-1" );
return ;
}
tree = new List<List< int >>();
for ( int i = 0; i <= N; i++)
{
tree.Add( new List< int >());
}
int src = 0;
for ( int i = 0; i < N; i++)
{
if (P[i] == -1)
{
src = i;
}
else
{
tree[i + 1].Add(P[i]);
tree[P[i]].Add(i + 1);
}
}
BFS(src, N + 1);
visited = new bool [N + 1];
DFS(src, W[src], W);
for ( int i = 0; i < N; i++)
{
if (i == src)
continue ;
visited = new bool [N + 1];
DFS(i + 1, W[i], W);
}
Console.WriteLine(maxDiff);
}
static void Main( string [] args)
{
int [] W = { 5, 10, 6, 12 };
int [] P = { 2, -1, 4, 2 };
int N = P.Length;
MaximumDiff(W, P, N);
}
}
|
Javascript
let tree = [];
let visited = [];
let ancestorNum = [];
let maxDiff = Number.MIN_SAFE_INTEGER;
function dfs(src, val, W)
{
visited[src] = true ;
for (let neighbour of tree[src])
{
if (!visited[neighbour] && ancestorNum[neighbour] > ancestorNum[src]) {
maxDiff = Math.max(val - W[neighbour - 1], maxDiff,6);
dfs(neighbour, val, W);
}
}
}
function bfs(src, N) {
visited = Array(N).fill( false );
let q = [];
ancestorNum[src] = 0;
visited[src] = true ;
q.push(src);
while (q.length > 0)
{
let cur = q.shift();
for (let neighbour of tree[cur])
{
if (!visited[neighbour])
{
visited[neighbour] = true ;
q.push(neighbour);
ancestorNum[neighbour] = ancestorNum[cur] + 1;
}
}
}
}
function maximumDiff(W, P, N) {
if (N === 1) {
console.log( "-1" );
return ;
}
tree= new Array(N + 1);
tree.fill([]);
visited = Array(N + 1).fill( false );
ancestorNum.length = N + 1;
ancestorNum.fill(0);
let src = 0;
for (let i = 0; i < N; i += 1) {
if (P[i] === -1) {
src = i;
} else {
tree[i + 1].push(P[i]);
tree[P[i]].push(i + 1);
}
}
bfs(src, N + 1);
visited = Array(N + 1).fill( false );
dfs(src, W[src], W);
for (let i = 0; i < N; i += 1) {
if (i === src) continue ;
visited = Array(N + 1).fill( false );
dfs(i + 1, W[i], W);
}
console.log(maxDiff);
}
maximumDiff([5, 10, 6, 12], [2, -1, 4, 2], 4);
|
Time Complexity: O(N2) Auxiliary Space: O(N)
|