给定一个n顶点的无向图,每一个顶点涂一种颜色,最多有m种颜色。 要求相邻顶点涂不同的颜色。问有多少种涂色方案?
如下实例,如果用至多4种颜色去涂它,有多少种方案?
可以用回溯法
解决此问题。每个顶点可能有4种涂色方案,共有5个顶点,因此解空间总共有
4
5
4^5
45种可能,除掉不符合要求的,最终结果如下:
代码如下:
#include <iostream>
#define MAX_V 100
using namespace std;
/* 图的m着色问题
* map : 图的邻接矩阵
* i : 当前递归的层次
* n : 图的顶点个数
* buf : 回溯缓冲区
* m : 颜色种类 [1, m]
* nums: 解的个数
* */
void done(int map[MAX_V][MAX_V], int i, int n, int buf[], int m, int& nums){
if(i >= n){
nums += 1;
return;
}
for(int a = 0; a < m; a++){
buf[i] = a + 1;
//剪枝
bool hasRepeated = false;
for(int b = 0; b < i; b++){ //注意这里是i
if(map[i][b] == 1 && buf[b] == buf[i]){
hasRepeated = true;
break;
}
}
if(!hasRepeated){
done(map, i + 1, n, buf, m, nums);
}
}
}
int main(){
int map[MAX_V][MAX_V] = {0};
int buf[5] = {0};
int nums = 0;
//构建图结构
map[0][1] = map[1][0] = 1;
map[0][2] = map[2][0] = 1;
map[0][3] = map[3][0] = 1;
map[1][2] = map[2][1] = 1;
map[1][3] = map[3][1] = 1;
map[1][4] = map[4][1] = 1;
map[2][3] = map[3][2] = 1;
map[3][4] = map[4][3] = 1;
done(map, 0, 5, buf, 4, nums);
cout << "solve count: " << nums << endl;
return 0;
}