Given a tree with N vertices numbered 1 through N with vertex 1 as root vertex and N – 1 edges. We have to color exactly k number of vertices and count the number of uncolored vertices between root vertex and every colored vertex. We have to include the root vertex in the count if it is not colored. The task to maximize the number of uncolored vertices occurring between the path from root vertex and the colored vertices.
Examples:
Input :
1
/ | \
/ | \
2 3 4
/ \ \
/ \ \
5 6 7
k = 4
Output : 7
Explanation:
If we color vertex 2, 5, 6 and 7,
the number of uncolored vertices between the path
from root to colored vertices is maximum which is 7.
Input :
1
/ \
/ \
2 3
/
/
4
k = 1
Output : 2
Approach:
To solve the above-mentioned problem we observe that if a vertex is chosen to be uncolored then its parent must be chosen to be uncolored. Then we can calculate how many uncolored vertices we will get if we choose a certain path to the colored vertex. Simply calculate the difference between the number of vertices between root to each vertex and the number of vertices that occur below the current vertex. Take the largest k of all the difference and calculate the sum. Use nth_element stl to get an O(n) solution.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool cmp( int a, int b)
{
return a > b;
}
class graph
{
vector<vector< int > > g;
vector< int > depth;
vector< int > subtree;
int * diff;
public :
graph( int n)
{
g = vector<vector< int > >(n + 1);
depth = vector< int >(n + 1);
subtree = vector< int >(n + 1);
diff = new int [n + 1];
}
void push( int a, int b)
{
g[a].push_back(b);
g[b].push_back(a);
}
int dfs( int v, int p)
{
depth[v] = depth[p] + 1;
subtree[v] = 1;
for ( auto i : g[v]) {
if (i == p)
continue ;
subtree[v] += dfs(i, v);
}
diff[v] = depth[v] - subtree[v];
return subtree[v];
}
void solution( int n, int k)
{
nth_element(diff + 1, diff + k, diff + n + 1, cmp);
int sum = 0;
for ( int i = 1; i <= k; i++) {
sum += diff[i];
}
cout << sum << "\n" ;
}
};
int main()
{
int N = 7;
int k = 4;
graph g(N);
g.push(1, 2);
g.push(1, 3);
g.push(1, 4);
g.push(3, 5);
g.push(3, 6);
g.push(4, 7);
g.dfs(1, 0);
g.solution(N, k);
return 0;
}
|
Python3
g = []
depth = []
subtree = []
diff = []
def graph(n):
global g, depth, subtree, diff
g = [[] for i in range (n + 1 )]
depth = [ 0 ] * (n + 1 )
subtree = [ 0 ] * (n + 1 )
diff = [ 0 ] * (n + 1 )
def push(a, b):
global g
g[a].append(b)
g[b].append(a)
def dfs(v, p):
global depth, subtree, g, diff
depth[v] = depth[p] + 1
subtree[v] = 1
for i in g[v]:
if (i = = p):
continue
subtree[v] + = dfs(i, v)
diff[v] = depth[v] - subtree[v]
return subtree[v]
def solution(n, k):
global diff
diff = sorted (diff)[:: - 1 ]
sum = 2
for i in range ( 1 , k + 1 ):
sum + = diff[i]
print ( sum )
if __name__ = = '__main__' :
N = 7
k = 4
graph(N)
push( 1 , 2 )
push( 1 , 3 )
push( 1 , 4 )
push( 3 , 5 )
push( 3 , 6 )
push( 4 , 7 )
dfs( 1 , 0 )
solution(N, k)
|
Javascript
<script>
let g = [];
let depth = [];
let subtree = [];
let diff = [];
function graph(n)
{
g = new Array(n + 1);
depth = Array(n + 1);
subtree = Array(n + 1);
diff = new Array(n + 1);
for (let i = 0; i < (n + 1); i++)
{
g[i] = [];
depth[i] = 0;
subtree[i] = 0;
diff[i] = 0;
}
}
function push(a, b)
{
g[a].push(b);
g[b].push(a);
}
function dfs(v, p)
{
depth[v] = depth[p] + 1;
subtree[v] = 1;
for (let i=0;i< g[v].length;i++) {
if (g[v][i] == p)
continue ;
subtree[v] += dfs(g[v][i], v);
}
diff[v] = depth[v] - subtree[v];
return subtree[v];
}
function solution(n, k)
{
diff.sort( function (a,b){ return b-a;});
let sum = 2,i;
for (i = 1; i < k + 1; i++)
{
sum += diff[i];
}
document.write(sum);
}
let N = 7,
k = 4;
graph(N)
push(1, 2)
push(1, 3)
push(1, 4)
push(3, 5)
push(3, 6)
push(4, 7)
dfs(1, 0)
solution(N, k)
</script>
|
Java
import java.util.*;
class Graph {
List<List<Integer> > g;
int [] depth;
int [] subtree;
int [] diff;
public Graph( int n)
{
g = new ArrayList<>(n + 1 );
for ( int i = 0 ; i <= n; i++) {
g.add( new ArrayList<>());
}
depth = new int [n + 1 ];
subtree = new int [n + 1 ];
diff = new int [n + 1 ];
}
public void push( int a, int b)
{
g.get(a).add(b);
g.get(b).add(a);
}
public int dfs( int v, int p)
{
depth[v] = depth[p] + 1 ;
subtree[v] = 1 ;
for ( int i : g.get(v)) {
if (i == p)
continue ;
subtree[v] += dfs(i, v);
}
diff[v] = depth[v] - subtree[v];
return subtree[v];
}
public void solution( int n, int k)
{
Arrays.sort(diff, 1 , n + 1 );
int sum = 0 ;
for ( int i = n; i >= n - k + 1 ; i--) {
sum += diff[i];
}
System.out.println(sum);
}
}
public class Main {
public static void main(String[] args)
{
int N = 7 ;
int k = 4 ;
Graph g = new Graph(N);
g.push( 1 , 2 );
g.push( 1 , 3 );
g.push( 1 , 4 );
g.push( 3 , 5 );
g.push( 3 , 6 );
g.push( 4 , 7 );
g.dfs( 1 , 0 );
g.solution(N, k);
}
}
|
C#
using System;
using System.Collections.Generic;
class Graph {
List<List< int > > g;
int [] depth;
int [] subtree;
int [] diff;
public Graph( int n)
{
g = new List<List< int > >(n + 1);
for ( int i = 0; i <= n; i++) {
g.Add( new List< int >());
}
depth = new int [n + 1];
subtree = new int [n + 1];
diff = new int [n + 1];
}
public void Push( int a, int b)
{
g[a].Add(b);
g[b].Add(a);
}
public int Dfs( int v, int p)
{
depth[v] = depth[p] + 1;
subtree[v] = 1;
foreach ( int i in g[v])
{
if (i == p)
continue ;
subtree[v] += Dfs(i, v);
}
diff[v] = depth[v] - subtree[v];
return subtree[v];
}
public void Solution( int n, int k)
{
if (k > n) {
Console.WriteLine(
"Error: k should be less than or equal to n." );
return ;
}
Array.Sort(diff, 1, n);
int sum = 2;
for ( int i = n - 1; i >=n - k; i--) {
sum += diff[i];
}
Console.WriteLine(sum);
}
}
class MainClass {
public static void Main( string [] args)
{
int N = 7;
int k = 4;
Graph g = new Graph(N);
g.Push(1, 2);
g.Push(1, 3);
g.Push(1, 4);
g.Push(3, 5);
g.Push(3, 6);
g.Push(4, 7);
g.Dfs(1, 0);
g.Solution(N, k);
}
}
|
Time Complexity: O(N), where N is the number of vertices.
Auxiliary Space: O(N), for using extra vectors of size N.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
26 Feb, 2023
Like Article
Save Article