Minimize colours to paint graph such that no path have same colour
Last Updated :
24 Mar, 2023
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++
#include <bits/stdc++.h>
using namespace std;
int minColour( int N, int M, vector< int > mat[])
{
vector<vector< int > > adj(N + 1);
vector< int > indeg(N + 1);
for ( int i = 0; i < M; i++) {
adj[(mat[i][0])].push_back(mat[i][1]);
indeg[(mat[i][1])]++;
}
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;
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 lvl;
}
int main()
{
int N = 5, M = 6;
vector< int > mat[] = { { 1, 3 }, { 2, 3 }, { 3, 4 }, { 1, 4 }, { 2, 5 }, { 3, 5 } };
cout << minColour(N, M, mat);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int minColour( int N, int M, int mat[][])
{
Vector<Integer>[] adj = new Vector[N + 1 ];
for ( int i = 0 ; i < N; i++)
adj[i] = new Vector<Integer>();
int [] indeg = new int [M];
for ( int i = 0 ; i < M; i++) {
adj[(mat[i][ 0 ])].add(mat[i][ 1 ]);
indeg[(mat[i][ 1 ])]++;
}
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 ;
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 lvl;
}
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 } };
System.out.print(minColour(N, M, mat));
}
}
|
Python3
def minColour(N, M, mat):
adj = [[] for _ in range (N + 1 )]
indeg = [ 0 for _ in range (N + 1 )]
for i in range ( 0 , M):
adj[(mat[i][ 0 ])].append(mat[i][ 1 ])
indeg[(mat[i][ 1 ])] + = 1
lvl = 0
q = []
for i in range ( 1 , N + 1 ):
if (indeg[i] = = 0 ):
q.append(i)
if ( len (q) = = 0 ):
return 0
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 lvl
if __name__ = = "__main__" :
N = 5
M = 6
mat = [[ 1 , 3 ], [ 2 , 3 ], [ 3 , 4 ], [ 1 , 4 ], [ 2 , 5 ], [ 3 , 5 ]]
print (minColour(N, M, mat))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int minColour( int N, int M, int [, ] mat)
{
List< int >[] adj = new List< int >[N + 1];
for ( int i = 0; i < N; i++)
adj[i] = new List< int >();
int [] indeg = new int [M];
for ( int i = 0; i < M; i++) {
adj[(mat[i, 0])].Add(mat[i, 1]);
indeg[(mat[i, 1])]++;
}
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;
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 lvl;
}
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 } };
Console.WriteLine(minColour(N, M, mat));
}
}
|
Javascript
function minColour(N, M, mat)
{
let adj = new Array(N + 1);
for ( var i = 0; i <= N; i++)
adj[i] = [];
let indeg = new Array(N + 1).fill(0);
for ( var i = 0; i < M; i++)
{
adj[(mat[i][0])].push(mat[i][1])
indeg[(mat[i][1])] += 1
}
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
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 lvl
}
let N = 5
let M = 6
let mat = [[1, 3], [2, 3], [3, 4], [1, 4], [2, 5], [3, 5]]
console.log(minColour(N, M, mat))
|
Time Complexity: O(N + M)
Auxiliary Space: O(N + M)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...