#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 */
标签:颜色,个点,int,sum,dfs,着色,color,回溯,解决 From: https://www.cnblogs.com/Jocelynn/p/17367080.html