3-coloring is NP Complete

3-shading is an exemplary NP-complete issue in chart hypothesis where the goal is to decide whether a given diagram can be hued utilizing three tones, to such an extent that no two neighboring vertices share a similar variety. The issue is delegated NP-complete, importance there is no known effective calculation to tackle it for all occasions, and checking a potential arrangement should be possible in polynomial time. Numerous other NP-complete issues can be decreased to 3-shading, showing its computational intricacy and its importance in understanding the more extensive class of NP-complete issues. Subsequently, 3-shading assumes a major part in the investigation of computational intricacy and calculation plan.

Methods Used

  • Backtracking

  • Exact Cover with 3-Sets

  • Reduction from 3-SAT


Backtracking is a deliberate algorithmic method used to tackle combinatorial issues by steadily fabricating likely arrangements and leaving those that neglect to meet specific circumstances. It investigates all potential ways to productively track down a legitimate arrangement. Backtracking can be carried out recursively or utilizing an express stack.


  • Begin with an unfilled variety task for all vertices.

  • Pick an uncolored vertex and relegate a variety (1, 2, or 3) to it.

  • Recursively apply stage 2 to generally uncolored neighbors of the ongoing vertex.

  • In the event that, at any time, a vertex has no legitimate variety that doesn't struggle with its neighbors, backtrack and attempt an alternate tone for the past vertex.

  • Rehash stages 2-4 until all vertices are shaded or it is resolved that no legitimate shading exists.


#include <iostream>
#include <vector>
using namespace std;

const int MAX_VERTICES = 100; 

vector<int> graph[MAX_VERTICES];
int color[MAX_VERTICES];

bool isBipartiteUtil(int v, int c) {
   color[v] = c;
   for (int u : graph[v]) {
      if (color[u] == c)
         return false;
      if (color[u] == 0 && !isBipartiteUtil(u, -c))
         return false;
   return true;

bool isBipartite(int numVertices) {
   for (int i = 0; i < numVertices; ++i) {
      if (color[i] == 0 && !isBipartiteUtil(i, 1))
         return false;
   return true;

int main() {
   int numVertices = 4;

   if (isBipartite(numVertices)) {
      cout << "Graph is Bipartite.
"; } else { cout << "Graph is not Bipartite.
"; } return 0; }


Graph is Bipartite.

Exact Cover with 3-Sets

Precise Cover with 3-Sets (X3C) is a particular variety of the Specific Cover issue, which is a NP-complete issue. In X3C, we are given a set X with an all out number of components n, and an assortment C of 3-component subsets of X. The inquiry is whether there exists a precise cover, i.e., a subcollection C' of C, with the end goal that every component in X shows up in precisely one subset in C'. As such, we need to find a bunch of disjoint 3-sets that covers all components of X precisely once.

To exhibit a decrease from 3-SAT to X3C, we will tell the best way to develop a case of X3C from a given occurrence of 3-SAT.


  • Build a Definite Cover issue with 3-sets from the given chart.

  • Utilize a calculation for tackling Definite Cover to track down a bunch of 3-sets that covers all vertices.

  • In the event that an answer exists, check assuming every 3-set contains remarkable vertices (no vertex is rehashed), and every vertex shows up in precisely one 3-set.

  • Assuming that all conditions are fulfilled, the diagram can be 3-hued. Any other way, it can't be 3-hued.


#include <iostream>
#include <vector>

bool hasDefiniteCover(const std::vector<std::vector<int>>& chart) {
   return false;

int main() {
   std::vector<std::vector<int>> chart = {
      {1, 2, 3},
      {4, 5, 6},
      {7, 8, 9},

   bool definiteCoverExists = hasDefiniteCover(chart);
   std::cout << "Definite Cover Exists: " << std::boolalpha << definiteCoverExists << std::endl;

   return 0;


Definite Cover Exists: false

Reduction from 3-SAT

In computational intricacy hypothesis, a "decrease" alludes to the most common way of changing over one issue (the source issue) into another issue (the objective issue) so that on the off chance that we can tackle the objective issue productively, we can likewise take care of the source issue effectively. The thought is to show that the source issue is no more earnestly than the objective issue.

3-SAT is a notable NP-complete issue. It is a choice issue where the information comprises of a Boolean equation in conjunctive ordinary structure (CNF) with three literals for each provision, and the inquiry is whether there exists a task of truth values to the factors that makes the whole recipe valid.

To show a decrease from 3-SAT to another issue, we should accept a model issue known as Vertex Cover (VC). Vertex Cover is likewise a NP-complete issue where the information is an undirected diagram G and a number k, and the inquiry is whether there exists a vertex front of size all things considered k. A vertex cover is a subset of vertices with the end goal that each edge in the chart is episode to something like one vertex in the subset.


  • Given a 3-SAT issue with factors and provisions, make a diagram where every variable relates to a vertex.

  • Interface vertices relating to the factors in a similar proviso and furthermore associate factors in correlative conditions (e.g., in the event that a statement has (x1 v x2 v ¬x3), associate vertices comparing to x1, x2, and ¬x3).

  • Check assuming that the subsequent diagram is 3-colorable.

  • In the event that the chart is 3-colorable, the 3-SAT issue has an answer, as well as the other way around.


#include <iostream>
#include <vector>

using namespace std;

bool isGraph3Colorable(const vector<vector<int>>& graph, int numVertices) {
   vector<int> colors(numVertices, -1);

   for (int vertex = 0; vertex < numVertices; ++vertex) {
      if (colors[vertex] == -1) {
         colors[vertex] = 0;
         vector<int> queue;

         while (!queue.empty()) {
            int current = queue.back();

            for (int neighbor : graph[current]) {
               if (colors[neighbor] == -1) {
                  colors[neighbor] = 1 - colors[current];
               } else if (colors[neighbor] == colors[current]) {
                  return false;

   return true;

vector<vector<int>> createDiagram(int numVariables, const vector<vector<int>>& clauses) {
   vector<vector<int>> diagram(numVariables * 3);

   for (int i = 0; i < clauses.size(); ++i) {
      int x = abs(clauses[i][0]) - 1;
      int y = abs(clauses[i][1]) - 1;
      int z = abs(clauses[i][2]) - 1;

      int xi = (clauses[i][0] < 0) ? x + 2 * numVariables : x;
      int yi = (clauses[i][1] < 0) ? y + 2 * numVariables : y;
      int zi = (clauses[i][2] < 0) ? z + 2 * numVariables : z;


   return diagram;

int main() {
   int numVariables = 3;
   vector<vector<int>> clauses = {{-1, 2, -3}, {1, -2, 3}, {2, 3, 1}};

   vector<vector<int>> diagram = createDiagram(numVariables, clauses);

   if (isGraph3Colorable(diagram, numVariables * 3)) {
      cout << "The diagram is 3-colorable. The 3-SAT issue has a solution." << endl;
   } else {
      cout << "The diagram is not 3-colorable. The 3-SAT issue does not have a solution." << endl;

   return 0;


The diagram is not 3-colorable. The 3-SAT issue does not have a solution.


The 3-shading issue is known to be NP-finished, and that implies there is no known polynomial-time calculation to address it for all examples. The methodologies depicted above are dramatic in nature, and their intricacy develops quickly with the size of the chart. Thus, for enormous charts, finding an ideal 3-shading probably won't be possible in a sensible measure of time. Nonetheless, these methodologies are fundamental for understanding the hypothetical parts of computational intricacy and the association between different NP-complete issues.

Updated on: 04-Aug-2023


Kickstart Your Career

Get certified by completing the course

Get Started