![]()
#include<iostream>
using namespace std;
int G[50][50]; //保存无向图
int color[50]; //存放每个点的颜色
int sum = 0; //需要的颜色总数
int mins = 999999; //需要的最少的颜色数
int N; //点的总个数
//检查点第i+1个点是否能放颜色c
bool check(int i, int c) {
bool flag = true;
for (int j = 0; j < i; j++) {
if (G[j][i] == 1) { //前面与第i+1个点直接相连的点
if (color[j] == c) //相连的点有颜色c
flag = false;
}
}
return flag;
}
//问题求解
void dfs(int i) {
if (i > N - 1) { //递归出口
if (sum < mins)
mins = sum; //记录最小颜色数
return; //有没有这句都一样,因为函数会自动返回(执行完函数体所有语句就返回)
}
else {
//对第i+1个结点,尝试已使用的所有颜色
int findColor = 0; //标记能否在已有颜色中找到可以使用的颜色
for (int j = 0; j < sum; j++) {
if (check(i, color[j])) { //如果颜色冲突,直接执行下一次for循环,不做任何操作(剪枝)
findColor = 1; //只要已有的颜色中有不冲突的,findColor就会被置为1
int sum1 = sum; //sum1是一个临时变量,记录了这次递归的颜色总数
color[i] = color[j]; //第i+1个点和第j+1个点颜色相同
dfs(i + 1); //在这个颜色满足条件的情况下,记录好这个颜色,然后求下一个点的颜色
sum = sum1; //回溯,(执行下一次for循环时,颜色总数应该不变,所以要回置颜色数)
}
}
if (findColor == 0) { //已有的颜色都不能用,已经走完了所有的颜色,所以不用回溯,而是去求下一个顶点的颜色
sum++; //总颜色数加一
color[i] = sum;
dfs(i + 1); //求下一个点的颜色
}
}
}
int main() {
cout << "请输入点的总个数" << endl;
cin >> N;
cout << "请输入二维矩阵表示的边的连接情况(1表示有边相连,0表示没有边相连)" << endl;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> G[i][j];
}
}
dfs(0);
cout << "最少颜色数: " << mins << endl;
system("pause");
}
/*
*
0 1 1 0 0
1 0 1 1 1
1 1 0 0 1
0 1 0 0 1
0 1 1 1 0
*/