M-Coloring Problem - GeeksforGeeks

M-Coloring Problem

Last Updated : 10 Nov, 2026

Given an undirected graph consisting of V vertices represented by an adjacency list adj[][] and an integer m, check whether the graph can be colored using at most m different colors such that no two adjacent vertices have the same color.

Note: The graph uses 0-based indexing and may be connected or disconnected.

Examples

Input: adj[][] = [[1, 3, 2], [0, 3], [3, 0], [1, 2, 0]], m = 3
Output: true
Explanation: Structure allows enough separation between connected vertices, so using 3 colors is sufficient to ensure no two adjacent vertices share the same color—hence, the answer is true

M-Coloring-Problem-2

Input: adj[][] = [[1, 2], [0, 2], [0, 1]], m = 2
Output: false
Explanation: It is not possible to color the given graph using only 2 colors because vertices 0, 1, and 2 form a triangle.

Try It Yourself
redirect icon

Generate All Colorings - O((V + E)*m^V) Time and O(V + E) Space

Generate all possible colorings of the V vertices. Since each vertex can have any of the m colors, there are (m^V) possible colorings.

  • For each coloring, check whether any two adjacent vertices have the same color.
  • If a valid coloring is found, return true.
  • If no valid coloring exists after checking all possibilities, return false.
C++
#include <bits/stdc++.h>
using namespace std;

// Function to check whether the current coloring is valid
bool goodcolor(vector<vector<int>> &adj, vector<int> col) {

    for (int i = 0; i < col.size(); i++) {
        for (auto it : adj[i]) {

            // Check if adjacent vertices have the same color
            if (i!= it && col[i] == col[it])
                return false;
        }
    }
    return true;
}

// Recursive function to generate all possible colorings
bool generateColor(int i, vector<int> col, int m, vector<vector<int>> &adj) {

    // If all vertices are colored, check whether the coloring is valid
    if (i >= col.size()) {
        if (goodcolor(adj, col))
            return true;

        return false;
    }

    // Try all colors from 0 to m-1
    for (int j = 0; j < m; j++) {
        col[i] = j;

        if (generateColor(i + 1, col, m, adj))
            return true;

        // Backtrack by resetting the current vertex color
        col[i] = -1;
    }

    return false;
}

// Function to check if the graph can be colored with m colors
bool graphColoring(vector<vector<int>> &adj, int m) {
    int v = adj.size();

    // Initialize all vertices with no color
    vector<int> color(v, -1);

    return generateColor(0, color, m, adj);
}

int main() {
    vector<vector<int>> adj = {
        {1, 2, 3},
        {0, 3},
        {0, 3},
        {0, 1, 2}
    };

    int m = 3;

    // Check if the graph can be colored with m colors
    // such that no adjacent vertices share the same color
    cout << (graphColoring(adj, m) ? "true" : "false") << endl;

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

class GFG {

    // Function to check whether the current coloring is valid
    static boolean goodcolor(ArrayList<ArrayList<Integer>> adj, ArrayList<Integer> col) {

        for (int i = 0; i < col.size(); i++) {
            for (int it : adj.get(i)) {

                // Check if adjacent vertices have the same color
                if (i!= it && col.get(i).equals(col.get(it)))
                    return false;
            }
        }
        return true;
    }

    // Recursive function to generate all possible colorings
    static boolean generateColor(int i, ArrayList<Integer> col, int m, ArrayList<ArrayList<Integer>> adj) {

        // If all vertices are colored, check whether the coloring is valid
        if (i >= col.size()) {
            if (goodcolor(adj, col))
                return true;

            return false;
        }

        // Try all colors from 0 to m-1
        for (int j = 0; j < m; j++) {
            col.set(i, j);

            if (generateColor(i + 1, new ArrayList<>(col), m, adj))
                return true;

            // Backtrack by resetting the current vertex color
            col.set(i, -1);
        }

        return false;
    }

    // Function to check if the graph can be colored with m colors
    static boolean graphColoring(ArrayList<ArrayList<Integer>> adj, int m) {
        int v = adj.size();

        // Initialize all vertices with no color
        ArrayList<Integer> color = new ArrayList<>(Collections.nCopies(v, -1));

        return generateColor(0, color, m, adj);
    }

    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> adj = new ArrayList<>();

        adj.add(new ArrayList<>(Arrays.asList(1, 2, 3)));
        adj.add(new ArrayList<>(Arrays.asList(0, 3)));
        adj.add(new ArrayList<>(Arrays.asList(0, 3)));
        adj.add(new ArrayList<>(Arrays.asList(0, 1, 2)));

        int m = 3;

        System.out.println(graphColoring(adj, m)? "true" : "false");
    }
}
Python
# Function to check whether the current coloring is valid
def goodcolor(adj, col):

    for i in range(len(col)):
        for it in adj[i]:

            # Check if adjacent vertices have the same color
            if i!= it and col[i] == col[it]:
                return False

    return True


# Recursive function to generate all possible colorings
def generateColor(i, col, m, adj):

    # If all vertices are colored, check whether the coloring is valid
    if i >= len(col):
        if goodcolor(adj, col):
            return True

        return False

    # Try all colors from 0 to m-1
    for j in range(m):
        col[i] = j

        if generateColor(i + 1, col.copy(), m, adj):
            return True

        # Backtrack by resetting the current vertex color
        col[i] = -1

    return False


# Function to check if the graph can be colored with m colors
def graphColoring(adj, m):
    v = len(adj)

    # Initialize all vertices with no color
    color = [-1] * v

    return generateColor(0, color, m, adj)


if __name__ == "__main__":
    adj = [
        [1, 2, 3],
        [0, 3],
        [0, 3],
        [0, 1, 2]
    ]

    m = 3

    print("true" if graphColoring(adj, m) else "false")
C#
using System;
using System.Collections.Generic;

class GFG {

    // Function to check whether the current coloring is valid
    static bool goodcolor(List<List<int>> adj, List<int> col) {

        for (int i = 0; i < col.Count; i++) {
            foreach (int it in adj[i]) {

                // Check if adjacent vertices have the same color
                if (i!= it && col[i] == col[it])
                    return false;
            }
        }
        return true;
    }

    // Recursive function to generate all possible colorings
    static bool generateColor(int i, List<int> col, int m, List<List<int>> adj) {

        // If all vertices are colored, check whether the coloring is valid
        if (i >= col.Count) {
            if (goodcolor(adj, col))
                return true;

            return false;
        }

        // Try all colors from 0 to m-1
        for (int j = 0; j < m; j++) {
            col[i] = j;

            if (generateColor(i + 1, new List<int>(col), m, adj))
                return true;

            // Backtrack by resetting the current vertex color
            col[i] = -1;
        }

        return false;
    }

    // Function to check if the graph can be colored with m colors
    static bool graphColoring(List<List<int>> adj, int m) {
        int v = adj.Count;

        // Initialize all vertices with no color
        List<int> color = new List<int>();

        for (int i = 0; i < v; i++)
            color.Add(-1);

        return generateColor(0, color, m, adj);
    }

    static void Main() {
        List<List<int>> adj = new List<List<int>> {
            new List<int> {1, 2, 3},
            new List<int> {0, 3},
            new List<int> {0, 3},
            new List<int> {0, 1, 2}
        };

        int m = 3;


        Console.WriteLine(graphColoring(adj, m)? "true" : "false");
    }
}
JavaScript
// Function to check whether the current coloring is valid
function goodcolor(adj, col) {

    for (let i = 0; i < col.length; i++) {
        for (let it of adj[i]) {

            // Check if adjacent vertices have the same color
            if (i!== it && col[i] === col[it])
                return false;
        }
    }
    return true;
}

// Recursive function to generate all possible colorings
function generateColor(i, col, m, adj) {

    // If all vertices are colored, check whether the coloring is valid
    if (i >= col.length) {
        if (goodcolor(adj, col))
            return true;

        return false;
    }

    // Try all colors from 0 to m-1
    for (let j = 0; j < m; j++) {
        col[i] = j;

        if (generateColor(i + 1, [...col], m, adj))
            return true;

        // Backtrack by resetting the current vertex color
        col[i] = -1;
    }

    return false;
}

// Function to check if the graph can be colored with m colors
function graphColoring(adj, m) {
    let v = adj.length;

    // Initialize all vertices with no color
    let color = new Array(v).fill(-1);

    return generateColor(0, color, m, adj);
}

// Driver code
let adj = [
    [1, 2, 3],
    [0, 3],
    [0, 3],
    [0, 1, 2]
];

let m = 3;

console.log(graphColoring(adj, m)? "true" : "false");

Output
true

Backtracking - O(V * m^V) Time and O(V + E) Space

Assign colors to vertices one by one, starting from vertex 0. Before assigning a color, check whether any adjacent vertex already has the same color.

  • Try all available colors from 0 to m-1 for the current vertex.
  • If a color is valid, assign it and recursively color the next vertex.
  • If no valid color is available, backtrack by resetting the current vertex's color and try another possibility.
  • If all vertices are colored successfully, return true; otherwise, return false.

Illustration:

C++
#include <bits/stdc++.h>
using namespace std;

// Function to check if it's safe to color the current vertex
// with the given color
bool issafe(int vertex, int col, vector<vector<int>> &adj, vector<int> &color) {
    for (auto it : adj[vertex]) {
        // If adjacent vertex has the same color, not safe
        if (color[it] != -1 && col == color[it])
            return false;
    }
    return true;
}

// Recursive function to try all colorings
bool cancolor(int vertex, int m, vector<vector<int>> &adj, vector<int> &color) {

    // If all vertices are colored successfully
    if (vertex == color.size())
        return true;

    // Try all colors from 0 to m-1
    for (int i = 0; i < m; i++) {
        if (issafe(vertex, i, adj, color)) {
            color[vertex] = i;

            if (cancolor(vertex + 1, m, adj, color))

                // If the rest can be colored, return true
                return true;

            color[vertex] = -1;
        }
    }

    // No valid coloring found
    return false;
}

bool graphColoring(vector<vector<int>> &adj, int m) {
    int v = adj.size();

    vector<int> color(v, -1);
    return cancolor(0, m, adj, color);
}

int main() {
    vector<vector<int>> adj = {
        {1, 2, 3},
        {0, 3},
        {0, 3},
        {0, 1, 2}
    };

    int m = 3;

    // Check if the graph can be colored with m colors
    // such that no adjacent vertices share the same color
    cout << (graphColoring(adj, m) ? "true" : "false") << endl;

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Arrays;

class GFG {

    // Function to check if it's safe to color the current vertex
    // with the given color
    static boolean issafe(int vertex, int col, ArrayList<ArrayList<Integer>> adj, ArrayList<Integer> color) {
        for (int it : adj.get(vertex)) {
            // If adjacent vertex has the same color, not safe
            if (color.get(it) != -1 && col == color.get(it))
                return false;
        }
        return true;
    }

    // Recursive function to try all colorings
    static boolean cancolor(int vertex, int m, ArrayList<ArrayList<Integer>> adj, ArrayList<Integer> color) {

        // If all vertices are colored successfully
        if (vertex == color.size())
            return true;

        // Try all colors from 0 to m-1
        for (int i = 0; i < m; i++) {
            if (issafe(vertex, i, adj, color)) {
                color.set(vertex, i);

                if (cancolor(vertex + 1, m, adj, color))

                    // If the rest can be colored, return true
                    return true;

                color.set(vertex, -1);
            }
        }

        // No valid coloring found
        return false;
    }

    static boolean graphColoring(ArrayList<ArrayList<Integer>> adj, int m) {
        int v = adj.size();

        ArrayList<Integer> color = new ArrayList<>(Collections.nCopies(v, -1));
        return cancolor(0, m, adj, color);
    }

    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> adj = new ArrayList<>();

        adj.add(new ArrayList<>(Arrays.asList(1, 2, 3)));
        adj.add(new ArrayList<>(Arrays.asList(0, 3)));
        adj.add(new ArrayList<>(Arrays.asList(0, 3)));
        adj.add(new ArrayList<>(Arrays.asList(0, 1, 2)));

        int m = 3;

        System.out.println(graphColoring(adj, m) ? "true" : "false");
    }
}
Python
# Function to check if it's safe to color the current vertex
# with the given color
def issafe(vertex, col, adj, color):
    for it in adj[vertex]:
        # If adjacent vertex has the same color, not safe
        if color[it] != -1 and col == color[it]:
            return False

    return True


# Recursive function to try all colorings
def cancolor(vertex, m, adj, color):

    # If all vertices are colored successfully
    if vertex == len(color):
        return True

    # Try all colors from 0 to m-1
    for i in range(m):
        if issafe(vertex, i, adj, color):
            color[vertex] = i

            if cancolor(vertex + 1, m, adj, color):

                # If the rest can be colored, return true
                return True

            color[vertex] = -1

    # No valid coloring found
    return False


def graphColoring(adj, m):
    v = len(adj)

    color = [-1] * v
    return cancolor(0, m, adj, color)


if __name__ == "__main__":
    adj = [
        [1, 2, 3],
        [0, 3],
        [0, 3],
        [0, 1, 2]
    ]

    m = 3

    print("true" if graphColoring(adj, m) else "false")
C#
using System;
using System.Collections.Generic;

class GFG {

    // Function to check if it's safe to color the current vertex
    // with the given color
    static bool issafe(int vertex, int col, List<List<int>> adj, List<int> color) {
        foreach (int it in adj[vertex]) {
            // If adjacent vertex has the same color, not safe
            if (color[it] != -1 && col == color[it])
                return false;
        }
        return true;
    }

    // Recursive function to try all colorings
    static bool cancolor(int vertex, int m, List<List<int>> adj, List<int> color) {

        // If all vertices are colored successfully
        if (vertex == color.Count)
            return true;

        // Try all colors from 0 to m-1
        for (int i = 0; i < m; i++) {
            if (issafe(vertex, i, adj, color)) {
                color[vertex] = i;

                if (cancolor(vertex + 1, m, adj, color))

                    // If the rest can be colored, return true
                    return true;

                color[vertex] = -1;
            }
        }

        // No valid coloring found
        return false;
    }

    static bool graphColoring(List<List<int>> adj, int m) {
        int v = adj.Count;

        List<int> color = new List<int>();

        // Initialize all vertices with no color
        for (int i = 0; i < v; i++)
            color.Add(-1);

        return cancolor(0, m, adj, color);
    }

    static void Main() {
        List<List<int>> adj = new List<List<int>> {
            new List<int> {1, 2, 3},
            new List<int> {0, 3},
            new List<int> {0, 3},
            new List<int> {0, 1, 2}
        };

        int m = 3;

        // Check if the graph can be colored with m colors
        // such that no adjacent vertices share the same color
        Console.WriteLine(graphColoring(adj, m) ? "true" : "false");
    }
}
JavaScript
// Function to check if it's safe to color the current vertex
// with the given color
function issafe(vertex, col, adj, color) {
    for (let it of adj[vertex]) {
        // If adjacent vertex has the same color, not safe
        if (color[it] !== -1 && col === color[it])
            return false;
    }
    return true;
}

// Recursive function to try all colorings
function cancolor(vertex, m, adj, color) {

    // If all vertices are colored successfully
    if (vertex === color.length)
        return true;

    // Try all colors from 0 to m-1
    for (let i = 0; i < m; i++) {
        if (issafe(vertex, i, adj, color)) {
            color[vertex] = i;

            if (cancolor(vertex + 1, m, adj, color))

                // If the rest can be colored, return true
                return true;

            color[vertex] = -1;
        }
    }

    // No valid coloring found
    return false;
}

function graphColoring(adj, m) {
    let v = adj.length;

    let color = new Array(v).fill(-1);
    return cancolor(0, m, adj, color);
}

// Driver code
let adj = [
    [1, 2, 3],
    [0, 3],
    [0, 3],
    [0, 1, 2]
];

let m = 3;

console.log(graphColoring(adj, m) ? "true" : "false");

Output
true

Time Complexity: O(V * m^V). There is a total of O(m^V) combinations of colors. For each attempted coloring of a vertex you call issafe(), can have up to V-1 neighbors, so issafe() is O(V)
Auxiliary Space: O(V + E). The recursive Stack of the graph coloring function will require O(V) space, Adjacency list and color array will required O(V+E).

Comment