给出一个无向图和一个数字m,此数字代表了允许使用颜色的种类,判断是否至多可以应用m种颜色,将图的每个顶点着色,并且相邻节点着的颜色不同。
输入:
1, 二维矩阵 graph[V][V],其中V代表图中顶点的个数,而矩阵本身是图的邻接矩阵表示形式。
2,对于graph[V][V]的理解是,graph[i][j], 如果i==j,那么graph[i][j]为1,或者i!= j,但是从顶点i到j有一条边
输出:
返回一个一位数组color[V], color[i] 的取值范围是1-m,代表第i个顶点图的颜色,同时要说明给定的矩阵是否可以被m涂色而且每两个相邻的节点颜色不同。
采用的方法应该是回溯算法:
算法的基本思想是,对于每个不同的节点,依次进行着色,在试图着色之后要进行判断,判断此节点的已经着色的临接节点中是否有和它着相同颜色的,如果有,那么此节点放弃当前的着色,改试使用其他颜色,最终,如果每一种颜色对此节点都不适用,那么就返回false,说明此图不能应用m种颜色对每个节点都着色而且每对相邻节点都能着不同的颜色。相反,如果此节点着以某种颜色能够满足与它邻接点颜色不一样的话,那么尝试对下一个节点着色,直至所有节点都被着色,而且每对邻接点的颜色都不一样,那我们就成功了。给定一个例子图如下:
给定解决方案代码如下,并且说明,对于一个图来说会有不止一个解决方案:
#include<iostream>
using namespace std;
const int V = 4;
void printSolution(int color[]) {
cout << "there existing solutions:" << endl;
int i;
for (i = 0; i < V; i++)
cout << color[i] << " ";
}
bool isSafe(int v, bool graph[V][V], int color[], int c) {
int i;
for (i = 0; i < V; i++)
if (graph[v][i] && c == color[i])
return false;
return true;
}
bool graphColoringUtil(bool graph[V][V], int m, int color[], int v) {
if (v == V)
return true;
int c;
for (c = 1; c <= m; c++) {
if (isSafe(v, graph, color, c)) {
color[v] = c;
if (graphColoringUtil(graph, m, color, v + 1))
return true;
else
color[v] = 0;
}
}
return false;
}
bool graphColoring(bool graph[V][V], int m) {
int *color = new int[V];
int i;
for (i = 0; i < V; i++)
color[i] = 0;
if (false == graphColoringUtil(graph, m, color, 0)) {
cout << "does not exist solution." << endl;
return false;
}
printSolution(color);
delete []color;
return true;
}
int main(int argc, char *argv[]) {
bool graph[V][V] = {{1, 1, 1, 1},
{1, 1, 1, 0},
{1, 1, 1, 1},
{1, 0, 1, 1},
};
int m = 3; // Number of colors
graphColoring(graph, m);
cin.get();
return 0;
}