Open In App

Minimum cost to colour a Tree with no 3 adjacent vertices having same colour

Last Updated : 29 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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:
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 = 6 

Input: 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++




// 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




# 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#




// 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


Javascript




<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




//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


Output: 

9

 

Time Complexity: O(N), where N is the number of nodes in the tree.
Auxiliary Space: O(N), for creating an additional array. 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads