Maximize sum of minimum difference of divisors of nodes in N-ary tree
Last Updated :
27 Mar, 2023
Given a n-ary tree having nodes with a particular weight, our task is to find out the maximum sum of the minimum difference of divisors of each node from root to leaf.
Examples:
Input:
18
/ \
7 15
/ \ \
4 12 2
/
9
Output: 10
Explanation:
The maximum sum is along the path 18 -> 7 -> 12 -> 9
Minimum difference between divisors of 18 = 6 – 3 = 3
Minimum difference between divisors of 7 = 7 – 1 = 6
Minimum difference between divisors of 12 = 4 – 3 = 1
Minimum difference between divisors of 9 = 3 – 3 = 0
Input:
20
/ \
13 14
/ \ \
10 8 26
/
25
Output: 17
Explanation:
The maximum sum is along the path 20 -> 14 -> 26
Approach:
To solve the problem mentioned above we can store the minimum difference between the divisors at each node in an array using the depth first traversal. Now, the task is to find out the minimum difference between the divisors.
- We can observe that for any number N, the smallest divisor x in the range [?N, N] will have the least difference between x and N/x.
- At each node, calculate the minimum difference between divisors, and finally start filling the array using the results of the children and calculate the maximum sum possible.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int sub[100005];
int minDivisorDifference( int n)
{
int num1;
int num2;
for ( int i = sqrt (n); i <= n; i++) {
if (n % i == 0) {
num1 = i;
num2 = n / i;
break ;
}
}
return abs (num1 - num2);
}
int dfs(vector< int > g[], int u, int par)
{
sub[u] = minDivisorDifference(u);
int mx = 0;
for ( auto c : g[u]) {
if (c != par) {
int ans = dfs(g, c, u);
mx = max(mx, ans);
}
}
sub[u] += mx;
return sub[u];
}
int main()
{
vector< int > g[100005];
int edges = 6;
g[18].push_back(7);
g[7].push_back(18);
g[18].push_back(15);
g[15].push_back(18);
g[15].push_back(2);
g[2].push_back(15);
g[7].push_back(4);
g[4].push_back(7);
g[7].push_back(12);
g[12].push_back(7);
g[12].push_back(9);
g[9].push_back(12);
int root = 18;
cout << dfs(g, root, -1);
}
|
Java
import java.util.Vector;
class GFG{
static int []sub = new int [ 100005 ];
static int minDivisorDifference( int n)
{
int num1 = 0 ;
int num2 = 0 ;
for ( int i = ( int ) Math.sqrt(n);
i <= n; i++)
{
if (n % i == 0 )
{
num1 = i;
num2 = n / i;
break ;
}
}
return Math.abs(num1 - num2);
}
static int dfs(Vector<Integer> g[],
int u, int par)
{
sub[u] = minDivisorDifference(u);
int mx = 0 ;
for ( int c : g[u])
{
if (c != par)
{
int ans = dfs(g, c, u);
mx = Math.max(mx, ans);
}
}
sub[u] += mx;
return sub[u];
}
public static void main(String[] args)
{
@SuppressWarnings ( "unchecked" )
Vector<Integer> []g =
new Vector[ 100005 ];
for ( int i = 0 ; i < g.length; i++)
g[i] = new Vector<Integer>();
int edges = 6 ;
g[ 18 ].add( 7 );
g[ 7 ].add( 18 );
g[ 18 ].add( 15 );
g[ 15 ].add( 18 );
g[ 15 ].add( 2 );
g[ 2 ].add( 15 );
g[ 7 ].add( 4 );
g[ 4 ].add( 7 );
g[ 7 ].add( 12 );
g[ 12 ].add( 7 );
g[ 12 ].add( 9 );
g[ 9 ].add( 12 );
int root = 18 ;
System.out.print(dfs(g, root, - 1 ));
}
}
|
Python3
import math
sub = [ 0 for i in range ( 100005 )]
def minDivisorDifference(n):
num1 = 0
num2 = 0
for i in range ( int (math.sqrt(n)), n + 1 ):
if (n % i = = 0 ):
num1 = i
num2 = n / / i
break
return abs (num1 - num2)
def dfs(g, u, par):
sub[u] = minDivisorDifference(u)
mx = 0
for c in g[u]:
if (c ! = par):
ans = dfs(g, c, u)
mx = max (mx, ans)
sub[u] + = mx
return sub[u]
if __name__ = = '__main__' :
g = [[] for i in range ( 100005 )]
edges = 6
g[ 18 ].append( 7 )
g[ 7 ].append( 18 )
g[ 18 ].append( 15 )
g[ 15 ].append( 18 )
g[ 15 ].append( 2 )
g[ 2 ].append( 15 )
g[ 7 ].append( 4 )
g[ 4 ].append( 7 )
g[ 7 ].append( 12 )
g[ 12 ].append( 7 )
g[ 12 ].append( 9 )
g[ 9 ].append( 12 )
root = 18
print (dfs(g, root, - 1 ))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int []sub = new int [100005];
static int minDivisorDifference( int n)
{
int num1 = 0;
int num2 = 0;
for ( int i = ( int ) Math.Sqrt(n);
i <= n; i++)
{
if (n % i == 0)
{
num1 = i;
num2 = n / i;
break ;
}
}
return Math.Abs(num1 - num2);
}
static int dfs(List< int > []g,
int u, int par)
{
sub[u] = minDivisorDifference(u);
int mx = 0;
foreach ( int c in g[u])
{
if (c != par)
{
int ans = dfs(g, c, u);
mx = Math.Max(mx, ans);
}
}
sub[u] += mx;
return sub[u];
}
public static void Main(String[] args)
{
List< int > []g =
new List< int >[100005];
for ( int i = 0; i < g.Length; i++)
g[i] = new List< int >();
int edges = 6;
g[18].Add(7);
g[7].Add(18);
g[18].Add(15);
g[15].Add(18);
g[15].Add(2);
g[2].Add(15);
g[7].Add(4);
g[4].Add(7);
g[7].Add(12);
g[12].Add(7);
g[12].Add(9);
g[9].Add(12);
int root = 18;
Console.Write(dfs(g, root, -1));
}
}
|
Javascript
<script>
let sub = new Array(100005);
sub.fill(0);
function minDivisorDifference(n)
{
let num1 = 0;
let num2 = 0;
for (let i = parseInt(Math.sqrt(n), 10); i <= n; i++)
{
if (n % i == 0)
{
num1 = i;
num2 = parseInt(n / i, 10);
break ;
}
}
return Math.abs(num1 - num2);
}
function dfs(g, u, par)
{
sub[u] = minDivisorDifference(u);
let mx = 0;
for (let c = 0; c < g[u].length; c++)
{
if (g[u] != par)
{
let ans = dfs(g, g[u], u);
mx = Math.max(mx, ans);
}
}
sub[u] += mx;
return sub[u];
}
let g = new Array(100005);
for (let i = 0; i < g.length; i++)
g[i] = [];
let edges = 6;
g[18].push(7);
g[7].push(18);
g[18].push(15);
g[15].push(18);
g[15].push(2);
g[2].push(15);
g[7].push(4);
g[4].push(7);
g[7].push(12);
g[12].push(7);
g[12].push(9);
g[9].push(12);
let root = 18;
document.write(dfs(g, root, -1));
</script>
|
Time Complexity: O(N3/2), where N is the number of nodes.
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...