问题描述:给定无向连通图G=(V,E) 和 m种不同的颜色,用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果一个图最少需要m种颜色才能使图中每条边连接的2个顶点着不同颜色,则称m为该图的色数。
这是一道非常典型的回溯题目。解法与“N皇后问题”一样。在填写每一个顶点的颜色时检查与相邻已填顶点的颜色是否相同。如果不同,则填上;如果相同(冲突),则另选一种;如果已没有颜色可供选择,则回溯到上一顶点。重复这一过程,直到所有顶点的颜色都已填上。
//图的m着色问题
public class Coloring {
static int n; // 图的顶点数
static int m; // 可用颜色数
static boolean [][] array; // 图的邻接矩阵
static long sum; // 可行解的m种着色方案
static int[] x; // 当前的解(每个顶点的颜色)
public static long mColoring(int mm){
m = mm;
sum = 0;
backtrack(1);
return sum;
}
public static int ok(int k){
for(int j=1;j<=n;j++){
if(array[k][j]&&(x[j]==x[k])){ //k与j之间相连并且j顶点的颜色与k顶点的颜色相同
return 0;
}
}
return 1;
}
public static void backtrack(int t) {
if (t > n) { //求出一种解, sum+1
sum++;
for(int i=1;i<=n;i++){
System.out.println(x[i] + ""); // 输出所有解(每个顶点的颜色)
System.out.println();
}
return;
}
for (int i = 1; i <= m; i++) {
x[t] = i; // 将这个顶点颜色赋为i
if (ok(t) == 1) { //检查是否满足条件
backtrack(t + 1); //递归查找
}
x[t] = 0; //回溯置为0
}
}