Skip to content
Related Articles

Related Articles

Minimize colours to paint graph such that no path have same colour

View Discussion
Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 26 Sep, 2022
View Discussion
Improve Article
Save Article

Given a directed graph with N nodes and M connections shown in the matrix mat[] where each element is of the form {xi, yi} denoting a directed edge from yi to xi. The task is to use the minimum number of colours to paint the nodes of the graph such that no two nodes in a path have the same colour. 

Examples:

Input: N = 5, M = 6, mat = {{1, 3},  {2, 3},  {3, 4}, {1, 4},  {2, 5},  {3, 5}}
Output: 3
Explanation: The graph nodes can be coloured as shown below
and that is the minimum number of colours possible.
 

Example 1

Example 1

Input: N = 3, M = 2, mat = {{1, 3}, {2, 3}}
Output: 2
Explanation: Here 1 and 2 can be assigned same colour and 3 another colour.

 

Approach: The problem can be solved using the concept of topological sorting as follows:

We can observe that the minimum number of colours required is the same as the length of the longest path of the graph.

All nodes having indegree = 0 can be assigned the same colour. Now remove one indegree from their neighbours and again iterate all the nodes with indegree = 0.

If this is followed, a node will be assigned a colour only when all the other nodes above it in all the paths are assigned a colour. So this will give the maximum length of  a path.

Follow the steps below to Implement the Idea:

  • Create an adjacency list for the directed graph from the given edges.
  • Maintain an indegree vector to store the indegrees of each node.
  • Declare a variable (say lvl) to store the depth of a node.
  • During each iteration of topological sorting a new color is taken and assigned to minions with indegree 0 and in each iteration lvl is incremented by one as a new color is taken.
  • Return the final value of lvl as the required answer.

Below is the implementation of the above approach:

C++




// C++ code for the above approach:
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find
// minimum number of colours required
int minColour(int N, int M, vector<int> mat[])
{
    // Create an adjacency list
    vector<vector<int> > adj(N + 1);
 
    // Create indeg to store
    // indegree of every minion
    vector<int> indeg(N + 1);
 
    for (int i = 0; i < M; i++) {
 
        // Store mat[i][1] in adj[mat[i][0]]
        // as mat[i][1] directs to mat[1][0]
        adj[mat[i][0]].push_back(mat[i][1]);
        indeg[mat[i][1]]++;
    }
 
    // Initialize a variable lvl to store min
    // different colors required
    int lvl = 0;
    queue<int> q;
 
    for (int i = 1; i <= N; i++) {
        if (indeg[i] == 0) {
            q.push(i);
        }
    }
 
    if (q.empty())
        return 0;
 
    // Loop to use Topological sorting
    while (!q.empty()) {
        int size = q.size();
        for (int k = 0; k < size; k++) {
            int e = q.front();
            q.pop();
 
            for (auto it : adj[e]) {
                indeg[it]--;
                if (indeg[it] == 0) {
                    q.push(it);
                }
            }
        }
        lvl++;
    }
 
    // Return the minimum number of colours
    return lvl;
}
 
// Driver code
int main()
{
    int N = 5, M = 6;
    vector<int> mat[] = { { 1, 3 }, { 2, 3 }, { 3, 4 }, { 1, 4 }, { 2, 5 }, { 3, 5 } };
 
    // Function Call
    cout << minColour(N, M, mat);
    return 0;
}

Java




// Java code for the above approach:
 
 
import java.util.*;
 
class GFG{
 
// Function to find
// minimum number of colours required
static int minColour(int N, int M, int mat[][])
{
    // Create an adjacency list
    Vector<Integer> []adj = new Vector[N + 1];
    for(int i = 0; i < N; i++)
        adj[i] = new Vector<Integer>();
 
    // Create indeg to store
    // indegree of every minion
    int []indeg = new int[M];
 
    for (int i = 0; i < M; i++) {
 
        // Store mat[i][1] in adj[mat[i][0]]
        // as mat[i][1] directs to mat[1][0]
        adj[mat[i][0]].add(mat[i][1]);
        indeg[mat[i][1]]++;
    }
 
    // Initialize a variable lvl to store min
    // different colors required
    int lvl = 0;
    Queue<Integer> q = new LinkedList<>();
 
    for (int i = 1; i <= N; i++) {
        if (indeg[i] == 0) {
            q.add(i);
        }
    }
 
    if (q.isEmpty())
        return 0;
 
    // Loop to use Topological sorting
    while (!q.isEmpty()) {
        int size = q.size();
        for (int k = 0; k < size; k++) {
            int e = q.peek();
            q.remove();
            if(adj[e]!=null)
            for (int it : adj[e]) {
                indeg[it]--;
                if (indeg[it] == 0) {
                    q.add(it);
                }
            }
        }
        lvl++;
    }
 
    // Return the minimum number of colours
    return lvl;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 5, M = 6;
    int [][]mat = { { 1, 3 }, { 2, 3 }, { 3, 4 }, { 1, 4 }, { 2, 5 }, { 3, 5 } };
 
    // Function Call
    System.out.print(minColour(N, M, mat));
}
}
 
// This code contributed by shikhasingrajput

Python3




# python code for the above approach:
 
# Function to find
# minimum number of colours required
def minColour(N, M, mat):
 
    # Create an adjacency list
    adj = [[] for _ in range(N + 1)]
 
    # Create indeg to store
    # indegree of every minion
    indeg = [0 for _ in range(N + 1)]
 
    for i in range(0, M):
 
        # Store mat[i][1] in adj[mat[i][0]]
        # as mat[i][1] directs to mat[1][0]
        adj[mat[i][0]].append(mat[i][1])
        indeg[mat[i][1]] += 1
 
    # Initialize a variable lvl to store min
    # different colors required
    lvl = 0
    q = []
 
    for i in range(1, N+1):
        if (indeg[i] == 0):
            q.append(i)
 
    if (len(q) == 0):
        return 0
 
    # Loop to use Topological sorting
    while (len(q) != 0):
        size = len(q)
        for k in range(0, size):
            e = q[0]
            q.pop(0)
 
            for it in adj[e]:
                indeg[it] -= 1
                if (indeg[it] == 0):
                    q.append(it)
 
        lvl += 1
 
    # Return the minimum number of colours
    return lvl
 
# Driver code
if __name__ == "__main__":
 
    N = 5
    M = 6
    mat = [[1, 3], [2, 3], [3, 4], [1, 4], [2, 5], [3, 5]]
 
    # Function Call
    print(minColour(N, M, mat))
 
# This code is contributed by rakeshsahni

C#




// C# code for the above approach:
 
using System;
using System.Collections.Generic;
 
class GFG {
 
    // Function to find
    // minimum number of colours required
    static int minColour(int N, int M, int[, ] mat)
    {
        // Create an adjacency list
        List<int>[] adj = new List<int>[ N + 1 ];
        for (int i = 0; i < N; i++)
            adj[i] = new List<int>();
 
        // Create indeg to store
        // indegree of every minion
        int[] indeg = new int[M];
 
        for (int i = 0; i < M; i++) {
 
            // Store mat[i][1] in adj[mat[i][0]]
            // as mat[i][1] directs to mat[1][0]
            adj[mat[i, 0]].Add(mat[i, 1]);
            indeg[mat[i, 1]]++;
        }
 
        // Initialize a variable lvl to store min
        // different colors required
        int lvl = 0;
        List<int> q = new List<int>();
 
        for (int i = 1; i <= N; i++) {
            if (indeg[i] == 0) {
                q.Add(i);
            }
        }
 
        if (q.Count == 0)
            return 0;
 
        // Loop to use Topological sorting
        while (q.Count != 0) {
            int size = q.Count;
            for (int k = 0; k < size; k++) {
                int e = q[0];
                q.RemoveAt(0);
                if (adj[e] != null)
                    foreach(int it in adj[e])
                    {
                        indeg[it]--;
                        if (indeg[it] == 0) {
                            q.Add(it);
                        }
                    }
            }
            lvl++;
        }
 
        // Return the minimum number of colours
        return lvl;
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        int N = 5, M = 6;
        int[, ] mat = { { 1, 3 }, { 2, 3 }, { 3, 4 },
                        { 1, 4 }, { 2, 5 }, { 3, 5 } };
 
        // Function Call
        Console.WriteLine(minColour(N, M, mat));
    }
}
 
// This code contributed by phasing17

Javascript




// JavaScript code for the above approach:
 
// Function to find
// minimum number of colours required
function minColour(N, M, mat)
{
    // Create an adjacency list
    let adj = new Array(N + 1);
    for (var i = 0; i <= N; i++)
        adj[i] = [];
 
    // Create indeg to store
    // indegree of every minion
    let indeg = new Array(N + 1).fill(0);
 
    for (var i = 0; i < M; i++)
    {
        // Store mat[i][1] in adj[mat[i][0]]
        // as mat[i][1] directs to mat[1][0]
        adj[mat[i][0]].push(mat[i][1])
        indeg[mat[i][1]] += 1
    }
     
     
    // Initialize a variable lvl to store min
    // different colors required
    let lvl = 0
    let q = []
 
    for (var i = 1; i <= N; i++)
    {
        if (indeg[i] == 0)
            q.push(i)
    }
 
    if (q.length == 0)
        return 0
 
    // Loop to use Topological sorting
    while (q.length != 0)
    {
        let size = q.length
        for (var k = 0; k < size; k++)
        {
            let e = q.shift()
 
            for (var it of adj[e])
            {
                indeg[it] -= 1
                if (indeg[it] == 0)
                    q.push(it)
            }
        }
 
        lvl += 1
    }
 
    // Return the minimum number of colours
    return lvl
}
 
 
// Driver code
 
let N = 5
let M = 6
let mat = [[1, 3], [2, 3], [3, 4], [1, 4], [2, 5], [3, 5]]
 
// Function Call
console.log(minColour(N, M, mat))
 
 
// This code is contributed by phasing17

Output

3

Time Complexity: O(N + M)
Auxiliary Space: O(N + M)


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!