Given n nodes with exactly n-1 edges and m persons (n >=m). At each node, you can either place a person or unlimited prizes for persons. Each person would be moving towards the root i.e. node 1 and will also grab the prize if they are available on that node. The task is to maximize the sum of prizes earned by all of them.
Examples:
Input: n = 7, m = 3
1
/ | \
2 3 4
/\ |
5 6 7
Output: 6
Explanation: If we place prizes at nodes 1, 2, 3, and 4 and place persons at nodes 5, 6, and 7. Then each of them would be getting 2 prizes. So, the total sum is 6.
Input: n = 3, m = 1
1
/ \
2 3
Output: 1
Approach: This can be solved by the following approach:
For each node we have to check if we place a person here, what would be sum of prizes a person would get. This can be done if for each node we calculate exactly how much prices can be distributed and arranging them in descending order to get maximum sum with in m.
Below are the steps involved:
- Create a adjancy list adj.
- Traverse in adj[] array, starting from node 1.
- For each node while traversing increase the depth by 1. Start traversing for that node.
-
Check if we place a person here, what would be sum of total prizes a person n would get here:
- Where each node is size[node] += traversal(ans, adj, a, node, depth + 1).
- Store them in size[node] – depth.
- Sort them in ans array in descending order.
- Collect total sum upto n – m.
- Return sum.
Below is the implementation of the above apprach:
// C++ Implementation of the code #include <bits/stdc++.h> #include <iostream> using namespace std;
vector< int > size;
// Function to find if we place prize here // what would be sum of prize int traversal(vector< long long >& ans,
vector<vector< int > >& adj, int node,
int parent, int depth)
{ size[node] = 1;
for ( auto a : adj[node]) {
if (a != parent) {
size[node]
+= traversal(ans, adj, a, node, depth + 1);
}
}
ans.push_back(size[node] - depth);
return size[node];
} // Function to find maximise sum of prizes // grabbed by persons. long long findMaxPrizes( int n, int m,
vector<vector< int > >& edges)
{ // code here
vector< long long > ans;
vector<vector< int > > adj(n + 1);
int i = 0;
size = vector< int >(n + 1, 0);
// Adding edges in adj
while (i < edges.size()) {
int x = edges[i][0];
int y = edges[i][1];
adj[x].push_back(y);
adj[y].push_back(x);
i++;
}
traversal(ans, adj, 1, -1, 1);
sort(ans.begin(), ans.end());
reverse(ans.begin(), ans.end());
i = 0;
long long sum = 0;
while (i < n - m) {
sum += ans[i];
i++;
}
return sum;
} // Driver code int main()
{ int n = 7;
int m = 3;
vector<vector< int > > edges
= { { 1, 2 }, { 1, 3 }, { 1, 4 },
{ 2, 5 }, { 2, 6 }, { 4, 7 } };
// Function call
cout << findMaxPrizes(n, m, edges);
return 0;
} |
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class Main {
// Global variable to store sizes of subtrees
static List<Integer> size;
// Function to perform depth-first traversal and calculate subtree sizes
static int traversal(List<Integer> ans, HashMap<Integer, List<Integer>> adj, int node, int parent, int depth) {
size.set(node, 1 );
for ( int a : adj.get(node)) {
if (a != parent) {
size.set(node, size.get(node) + traversal(ans, adj, a, node, depth + 1 ));
}
}
ans.add(size.get(node) - depth);
return size.get(node);
}
// Function to find the maximum sum of prizes grabbed by persons
static int findMaxPrizes( int n, int m, int [][] edges) {
List<Integer> ans = new ArrayList<>();
// Using HashMap to represent an adjacency list
HashMap<Integer, List<Integer>> adj = new HashMap<>();
size = new ArrayList<>(Collections.nCopies(n + 1 , 0 ));
// Populating the adjacency list
for ( int [] edge : edges) {
int x = edge[ 0 ];
int y = edge[ 1 ];
adj.computeIfAbsent(x, k -> new ArrayList<>()).add(y);
adj.computeIfAbsent(y, k -> new ArrayList<>()).add(x);
}
// Performing depth-first traversal to calculate subtree sizes
traversal(ans, adj, 1 , - 1 , 1 );
// Sorting the list of subtree sizes in descending order
Collections.sort(ans, Collections.reverseOrder());
int i = 0 ;
int totalSum = 0 ;
// Calculating the sum of prizes for the top (n - m) sizes
while (i < n - m) {
totalSum += ans.get(i);
i++;
}
return totalSum;
}
// Driver code
public static void main(String[] args) {
int n = 7 ;
int m = 3 ;
int [][] edges = {{ 1 , 2 }, { 1 , 3 }, { 1 , 4 }, { 2 , 5 }, { 2 , 6 }, { 4 , 7 }};
// Function call
System.out.println(findMaxPrizes(n, m, edges));
}
} |
from collections import defaultdict
# Global variable to store sizes of subtrees size = []
# Function to perform depth-first traversal and calculate subtree sizes def traversal(ans, adj, node, parent, depth):
size[node] = 1
for a in adj[node]:
if a ! = parent:
size[node] + = traversal(ans, adj, a, node, depth + 1 )
ans.append(size[node] - depth)
return size[node]
# Function to find the maximum sum of prizes grabbed by persons def findMaxPrizes(n, m, edges):
ans = []
# Using defaultdict to represent an adjacency list
adj = defaultdict( list )
global size
size = [ 0 ] * (n + 1 )
# Populating the adjacency list
for edge in edges:
x, y = edge
adj[x].append(y)
adj[y].append(x)
# Performing depth-first traversal to calculate subtree sizes
traversal(ans, adj, 1 , - 1 , 1 )
# Sorting the list of subtree sizes in descending order
ans.sort(reverse = True )
i = 0
total_sum = 0
# Calculating the sum of prizes for the top (n - m) sizes
while i < n - m:
total_sum + = ans[i]
i + = 1
return total_sum
# Driver code if __name__ = = "__main__" :
n = 7
m = 3
edges = [[ 1 , 2 ], [ 1 , 3 ], [ 1 , 4 ], [ 2 , 5 ], [ 2 , 6 ], [ 4 , 7 ]]
# Function call
print (findMaxPrizes(n, m, edges))
|
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{ static List< int > size;
// Function to find if we place prize here
// what would be sum of prize
static int Traversal(List< long > ans, List<List< int >> adj,
int node, int parent, int depth)
{
size[node] = 1;
foreach ( var a in adj[node])
{
if (a != parent)
{
size[node] += Traversal(ans, adj, a, node, depth + 1);
}
}
ans.Add(size[node] - depth);
return size[node];
}
// Function to find maximise sum of prizes
// grabbed by persons.
static long FindMaxPrizes( int n, int m, List<List< int >> edges)
{
List< long > ans = new List< long >();
List<List< int >> adj = new List<List< int >>(n + 1);
for ( int i = 0; i <= n; i++)
{
adj.Add( new List< int >());
}
int index = 0;
size = new List< int >( new int [n + 1]);
// Adding edges in adj
foreach ( var edge in edges)
{
int x = edge[0];
int y = edge[1];
adj[x].Add(y);
adj[y].Add(x);
index++;
}
Traversal(ans, adj, 1, -1, 1);
ans.Sort();
ans.Reverse();
index = 0;
long sum = 0;
while (index < n - m)
{
sum += ans[index];
index++;
}
return sum;
}
// Driver code
public static void Main( string [] args)
{
int n = 7;
int m = 3;
List<List< int >> edges = new List<List< int >>
{
new List< int > { 1, 2 }, new List< int > { 1, 3 }, new List< int > { 1, 4 },
new List< int > { 2, 5 }, new List< int > { 2, 6 }, new List< int > { 4, 7 }
};
// Function call
Console.WriteLine(FindMaxPrizes(n, m, edges));
}
} // This code is contributed by SHIVAMGUPTA0987654321 |
<script> // Function to perform depth-first traversal and calculate subtree sizes function traversal(ans, adj, node, parent, depth, size) {
size[node] = 1;
// Use get method to retrieve the adjacency list for the node
for (let a of adj.get(node) || []) {
if (a !== parent) {
size[node] += traversal(ans, adj, a, node, depth + 1, size);
}
}
ans.push(size[node] - depth);
return size[node];
} // Function to find the maximum sum of prizes grabbed by persons function findMaxPrizes(n, m, edges) {
let ans = [];
// Using Map to represent an adjacency list
let adj = new Map();
let size = Array(n + 1).fill(0);
// Populating the adjacency list
for (let edge of edges) {
let x = edge[0];
let y = edge[1];
adj.set(x, (adj.get(x) || []).concat(y));
adj.set(y, (adj.get(y) || []).concat(x));
}
// Performing depth-first traversal to calculate subtree sizes
traversal(ans, adj, 1, -1, 1, size);
// Sorting the list of subtree sizes in descending order
ans.sort((a, b) => b - a);
let i = 0;
let totalSum = 0;
// Calculating the sum of prizes for the top (n - m) sizes
while (i < n - m) {
totalSum += ans[i];
i++;
}
return totalSum;
} // Driver code let n = 7; let m = 3; let edges = [[1, 2], [1, 3], [1, 4], [2, 5], [2, 6], [4, 7]]; // Function call console.log(findMaxPrizes(n, m, edges)); </script> |
6
Complexity Analysis:
Time Complexity: O(n log n)
Auxiliary Space: O(n)