Given a tree with N nodes value from 0 to (N – 1) and a 2D array arr[][] of size dimensions 3xN, where arr[i][j] denotes the cost of coloring jth nodes with color value i. The task is to find the minimum cost of coloring the node of the given tree such that every path of length 3 is colored with distinct colors. If there is any possible way of colouring the nodes of the tree then print the cost else print “Not Possible”.
Examples:
Input: arr[][] = {{3, 2, 3}, {4, 3, 2}, {3, 1, 3}},
Tree:
Output: 6
Explanation:
Color the vertex 0 with type 1 color, cost = 3
Color the vertex 1 with type 3 color, cost = 1
Color the vertex 2 with type 2 color, cost = 2
Therefore the minimum cost is 3 + 1 + 2 = 6Input: arr[][] = {{3, 4, 2, 1, 2}, {4, 2, 1, 5, 4}, {5, 3, 2, 1, 1}},
Tree:
Output: NOT POSSIBLE
Approach: The idea is to make an observation. We need to observe that the answer is not possible if there is a vertex that has more than two edges. The answer exists only for a chain structure, i.e.,
- Initially, we check if, for any node, there exist more than two children or not.
- If there exist, then the answer is not possible.
- If there doesn’t exist, then there are only 3P2 available permutations. So, simply check for all the six possible permutations and find the minimum cost.
Below is the implementation of the above approach:
// C++ program to find the // minimum possible cost // to colour a given tree #include <bits/stdc++.h> using namespace std;
// Class to define a tree class tree {
vector<vector< int > > g;
vector< int > chain;
int minimum;
public :
// Constructor
tree( int n)
{
g = vector<vector< int > >(n);
minimum = 1e6;
}
// Function for pushing edges
void addEdge( int u, int v)
{
g[v].push_back(u);
g[u].push_back(v);
}
// Dfs function to make the chain
// structure of tree in a vector
void dfs( int v, int p = -1)
{
chain.push_back(v);
for ( auto i : g[v]) {
if (i == p)
continue ;
dfs(i, v);
}
}
// Function that checks all the
// six different type of
// coloring and find the
// minimum of them
void check( int n, int a, int b,
vector<vector< int > > cost)
{
int sum = 0;
vector< int > res(n);
// Assign the color type 1
// to the first element
res[0] = a;
// Assign the color type 2
// to the second element
res[1] = b;
// Add the cost of the color
// of the first element
sum += cost[a][chain[0]];
// Add the cost of the color
// of the second element
sum += cost[b][chain[1]];
for ( int i = 2; i < n; i++) {
// Assign the next element in chain
// with different color
res[i] = 3 - res[i - 1] - res[i - 2];
// Add the cost of the element color
sum += cost[res[i]][chain[i]];
}
// Finding the minimum from all cases
if (sum < minimum)
minimum = sum;
}
// Function to find the
// minimum possible cost
// to colour a given tree
void minimumCost( int n,
vector<vector< int > > cost)
{
for ( int i = 0; i < n; i++) {
// Condition to check if
// any vertex consists more than
// 2 edges, then the coloring of
// the vertices is not possible
if (g[i].size() > 2) {
cout << "NOT POSSIBLE"
<< "\n" ;
return ;
}
}
int start;
// Find the starting/ending vertex
for ( int i = 0; i < n; i++) {
if (g[i].size() == 1)
start = i;
}
// Call dfs function starting from
// the start vertex
dfs(start);
// Check for all six different
// possible cases
check(n, 0, 1, cost);
check(n, 0, 2, cost);
check(n, 1, 0, cost);
check(n, 1, 2, cost);
check(n, 2, 0, cost);
check(n, 2, 1, cost);
// Printing the minimum cost
cout << minimum << "\n" ;
}
}; // Driver code int main()
{ tree t(5);
t.addEdge(0, 1);
t.addEdge(1, 2);
t.addEdge(2, 3);
t.addEdge(3, 4);
vector<vector< int > > arr
= { { 3, 4, 2, 1, 2 },
{ 4, 2, 1, 5, 4 },
{ 5, 3, 2, 1, 1 } };
t.minimumCost(5, arr);
return 0;
} |
# Python3 program to find the # minimum possible cost # to colour a given tree # Class to define a tree class tree:
def __init__( self , n):
self .g = [[] for i in range (n)]
self .minimum = 1000000
self .chain = []
# Function for pushing edges
def addEdge( self , u, v):
self .g[v].append(u);
self .g[u].append(v);
# Dfs function to make the chain
# structure of tree in a vector
def dfs( self , v, p = - 1 ):
self .chain.append(v);
for i in self .g[v]:
if (i = = p):
continue ;
self .dfs(i, v);
# Function that checks all the
# six different type of
# coloring and find the
# minimum of them
def check( self , n, a, b, cost):
sum = 0 ;
res = [ 0 for i in range (n)]
# Assign the color type 1
# to the first element
res[ 0 ] = a;
# Assign the color type 2
# to the second element
res[ 1 ] = b;
# Add the cost of the color
# of the first element
sum + = cost[a][ self .chain[ 0 ]];
# Add the cost of the color
# of the second element
sum + = cost[b][ self .chain[ 1 ]];
for i in range ( 2 , n):
# Assign the next element in chain
# with different color
res[i] = 3 - res[i - 1 ] - res[i - 2 ];
# Add the cost of the element color
sum + = cost[res[i]][ self .chain[i]];
# Finding the minimum from all cases
if ( sum < self .minimum):
self .minimum = sum ;
# Function to find the
# minimum possible cost
# to colour a given tree
def minimumCost( self , n, cost):
for i in range (n):
# Condition to check if
# any vertex consists more than
# 2 edges, then the coloring of
# the vertices is not possible
if ( len ( self .g[i]) > 2 ):
print ( "NOT POSSIBLE" )
return ;
start = 0
# Find the starting/ending vertex
for i in range (n):
if ( len ( self .g[i]) = = 1 ):
start = i;
# Call dfs function starting from
# the start vertex
self .dfs(start);
# Check for all six different
# possible cases
self .check(n, 0 , 1 , cost);
self .check(n, 0 , 2 , cost);
self .check(n, 1 , 0 , cost);
self .check(n, 1 , 2 , cost);
self .check(n, 2 , 0 , cost);
self .check(n, 2 , 1 , cost);
# Printing the minimum cost
print ( self .minimum)
# Driver code if __name__ = = '__main__' :
t = tree( 5 );
t.addEdge( 0 , 1 );
t.addEdge( 1 , 2 );
t.addEdge( 2 , 3 );
t.addEdge( 3 , 4 );
arr = [[ 3 , 4 , 2 , 1 , 2 ],
[ 4 , 2 , 1 , 5 , 4 ],
[ 5 , 3 , 2 , 1 , 1 ]];
t.minimumCost( 5 , arr);
# This code is contributed by rutvik_56 |
// C# program to find the // minimum possible cost // to colour a given tree using System;
using System.Collections;
using System.Collections.Generic;
// Class to define a tree class tree{
public ArrayList g;
public ArrayList chain;
public int minimum;
// Constructor tree( int n)
{ g = new ArrayList();
chain = new ArrayList();
for ( int i = 0; i < n; i++)
{
g.Add( new ArrayList());
}
minimum = 1000000;
} // Function for pushing edges void addEdge( int u, int v)
{ ((ArrayList)g[v]).Add(u);
((ArrayList)g[u]).Add(v);
} // Dfs function to make the chain // structure of tree in a vector void dfs( int v, int p = -1)
{ chain.Add(v);
foreach ( int i in (ArrayList)g[v])
{
if (i == p)
continue ;
dfs(i, v);
}
} // Function that checks all the // six different type of // coloring and find the // minimum of them void check( int n, int a, int b,
ArrayList cost)
{ int sum = 0;
ArrayList res = new ArrayList();
for ( int i = 0; i < n; i++)
{
res.Add(0);
}
// Assign the color type 1
// to the first element
res[0] = a;
// Assign the color type 2
// to the second element
res[1] = b;
// Add the cost of the color
// of the first element
sum += ( int )((ArrayList)cost[a])[( int )chain[0]];
// Add the cost of the color
// of the second element
sum += ( int )((ArrayList)cost[b])[( int )chain[1]];
for ( int i = 2; i < n; i++)
{
// Assign the next element in chain
// with different color
res[i] = 3 - ( int )res[i - 1] - ( int )res[i - 2];
// Add the cost of the element color
sum += ( int )((ArrayList)cost[(
int )res[i]])[( int )chain[i]];
}
// Finding the minimum from all cases
if (sum < minimum)
minimum = sum;
} // Function to find the // minimum possible cost // to colour a given tree void minimumCost( int n,
ArrayList cost)
{ for ( int i = 0; i < n; i++)
{
// Condition to check if
// any vertex consists more than
// 2 edges, then the coloring of
// the vertices is not possible
if (((ArrayList)g[i]).Count > 2)
{
Console.WriteLine( "NOT POSSIBLE" );
return ;
}
}
int start = 0;
// Find the starting/ending vertex
for ( int i = 0; i < n; i++)
{
if (((ArrayList)g[i]).Count == 1)
start = i;
}
// Call dfs function starting from
// the start vertex
dfs(start);
// Check for all six different
// possible cases
check(n, 0, 1, cost);
check(n, 0, 2, cost);
check(n, 1, 0, cost);
check(n, 1, 2, cost);
check(n, 2, 0, cost);
check(n, 2, 1, cost);
// Printing the minimum cost
Console.WriteLine(minimum);
} // Driver code public static void Main( string []args)
{ tree t = new tree(5);
t.addEdge(0, 1);
t.addEdge(1, 2);
t.addEdge(2, 3);
t.addEdge(3, 4);
ArrayList arr = new ArrayList();
arr.Add( new ArrayList(){ 3, 4, 2, 1, 2 });
arr.Add( new ArrayList(){ 4, 2, 1, 5, 4 });
arr.Add( new ArrayList(){ 5, 3, 2, 1, 1 });
t.minimumCost(5, arr);
} } // This code is contributed by pratham76 |
<script> // Javascript program to find the
// minimum possible cost
// to colour a given tree
let g = [];
let chain = [];
let minimum;
// Class to define a tree
class tree
{
constructor(n) {
for (let i = 0; i < n; i++)
{
g.push([]);
}
minimum = 1000000;
}
}
// Function for pushing edges
function addEdge(u, v)
{
g[v].push(u);
g[u].push(v);
}
// Dfs function to make the chain
// structure of tree in a vector
function dfs(v, p = -1)
{
chain.push(v);
for (let i = 0; i < g[v].length; i++)
{
if (g[v][i] == p)
continue ;
dfs(g[v][i], v);
}
}
// Function that checks all the
// six different type of
// coloring and find the
// minimum of them
function check(n, a, b, cost)
{
let sum = 0;
let res = [];
for (let i = 0; i < n; i++)
{
res.push(0);
}
// Assign the color type 1
// to the first element
res[0] = a;
// Assign the color type 2
// to the second element
res[1] = b;
// Add the cost of the color
// of the first element
sum += (cost[a])[chain[0]];
// Add the cost of the color
// of the second element
sum += (cost[b])[chain[1]];
for (let i = 2; i < n; i++)
{
// Assign the next element in chain
// with different color
res[i] = 3 - res[i - 1] - res[i - 2];
// Add the cost of the element color
sum += (cost[res[i]])[chain[i]];
}
// Finding the minimum from all cases
if (sum < minimum)
minimum = sum;
}
// Function to find the
// minimum possible cost
// to colour a given tree
function minimumCost(n, cost)
{
for (let i = 0; i < n; i++)
{
// Condition to check if
// any vertex consists more than
// 2 edges, then the coloring of
// the vertices is not possible
if ((g[i]).length > 2)
{
document.write( "NOT POSSIBLE" );
return ;
}
}
let start = 0;
// Find the starting/ending vertex
for (let i = 0; i < n; i++)
{
if ((g[i]).length == 1)
start = i;
}
// Call dfs function starting from
// the start vertex
dfs(start);
// Check for all six different
// possible cases
check(n, 0, 1, cost);
check(n, 0, 2, cost);
check(n, 1, 0, cost);
check(n, 1, 2, cost);
check(n, 2, 0, cost);
check(n, 2, 1, cost);
// Printing the minimum cost
document.write(minimum);
}
let t = new tree(5);
addEdge(0, 1);
addEdge(1, 2);
addEdge(2, 3);
addEdge(3, 4);
let arr = [];
arr.push([ 3, 4, 2, 1, 2 ]);
arr.push([ 4, 2, 1, 5, 4 ]);
arr.push([ 5, 3, 2, 1, 1 ]);
minimumCost(5, arr);
// This code is contributed by mukesh07. </script> |
//Java code for the above approach import java.util.ArrayList;
// Class to define a tree class Tree {
public ArrayList<ArrayList<Integer> > g;
public ArrayList<Integer> chain;
public int minimum;
// Constructor
Tree( int n)
{
g = new ArrayList<>();
chain = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
g.add( new ArrayList<>());
}
minimum = 1000000 ;
}
// Function for pushing edges
void addEdge( int u, int v)
{
g.get(v).add(u);
g.get(u).add(v);
}
// Dfs function to make the chain
// structure of tree in a vector
// Dfs function to make the chain
// structure of tree in a vector void dfs( int v, int p) {
// Add default value for p
if (p == - 1 ) {
p = - 2 ;
}
chain.add(v);
for ( int i : g.get(v)) {
if (i == p) {
continue ;
}
dfs(i, v);
}
} // Function that checks all the
// six different type of
// coloring and find the
// minimum of them
void check( int n, int a, int b,
ArrayList<ArrayList<Integer> > cost)
{
int sum = 0 ;
ArrayList<Integer> res = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
res.add( 0 );
}
// Assign the color type 1
// to the first element
res.set( 0 , a);
// Assign the color type 2
// to the second element
res.set( 1 , b);
// Add the cost of the color
// of the first element
sum += cost.get(a).get(chain.get( 0 ));
// Add the cost of the color
// of the second element
sum += cost.get(b).get(chain.get( 1 ));
for ( int i = 2 ; i < n; i++) {
// Assign the next element in chain
// with different color
res.set(i, 3 - res.get(i - 1 ) - res.get(i - 2 ));
// Add the cost of the element color
sum += cost.get(res.get(i)).get(chain.get(i));
}
// Finding the minimum from all cases
if (sum < minimum) {
minimum = sum;
}
}
// Function to find the
// minimum possible cost
// to colour a given tree
void minimumCost( int n,
ArrayList<ArrayList<Integer> > cost)
{
for ( int i = 0 ; i < n; i++) {
// Condition to check if
// any vertex consists more than
// 2 edges, then the coloring of
// the vertices is not possible
if (g.get(i).size() > 2 ) {
System.out.println( "NOT POSSIBLE" );
return ;
}
}
int start = 0 ;
// Find the starting/ending vertex
for ( int i = 0 ; i < n; i++) {
if (g.get(i).size() == 1 ) {
start = i;
}
}
// Call dfs function starting from
// the start vertex
dfs(start,- 1 );
// Check for all six different
// possible cases
check(n, 0 , 1 , cost);
check(n, 0 , 2 , cost);
check(n, 1 , 0 , cost);
check(n, 1 , 2 , cost);
check(n, 2 , 0 , cost);
check(n, 2 , 1 , cost);
// Printing the minimum cost
System.out.println(minimum);
}
} // Driver code public class Main {
public static void main(String[] args)
{
Tree t = new Tree( 5 );
t.addEdge( 0 , 1 );
t.addEdge( 1 , 2 );
t.addEdge( 2 , 3 );
t.addEdge( 3 , 4 );
ArrayList<ArrayList<Integer> > arr
= new ArrayList<>();
arr.add( new ArrayList<>());
arr.add( new ArrayList<>());
arr.add( new ArrayList<>());
arr.get( 0 ).add( 3 );
arr.get( 0 ).add( 4 );
arr.get( 0 ).add( 2 );
arr.get( 0 ).add( 1 );
arr.get( 0 ).add( 2 );
arr.get( 1 ).add( 4 );
arr.get( 1 ).add( 2 );
arr.get( 1 ).add( 1 );
arr.get( 1 ).add( 5 );
arr.get( 1 ).add( 4 );
arr.get( 2 ).add( 5 );
arr.get( 2 ).add( 3 );
arr.get( 2 ).add( 2 );
arr.get( 2 ).add( 1 );
arr.get( 2 ).add( 1 );
t.minimumCost( 5 , arr);
}
} //This code is contributed by Potta Lokesh |
9
Time Complexity: O(N), where N is the number of nodes in the tree.
Auxiliary Space: O(N), for creating an additional array.