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

• Difficulty Level : Medium
• Last Updated : 26 Sep, 2022

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

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 ` `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 > 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 []adj = ``new` `Vector[N + ``1``];` `    ``for``(``int` `i = ``0``; i < N; i++)` `        ``adj[i] = ``new` `Vector();`   `    ``// 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 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
Related Articles