5.6 求解图的m着色问题_c++

5.6 求解图的m着色问题_#define_02

#include <bits/stdc++.h>
using namespace std;
#define MAXN 20

// 问题表示
int n, k, m;
int a[MAXN][MAXN];
// 求解结果表示
int x[MAXN]; // x[i]表示顶点i的着色

bool Same(int i){
for(int j = 1; j <= n; j++)
if(a[i][j] == 1 && x[i] == x[j])
return false;
return true;
}

void dfs(int i, int &count){
if(i > n)
count ++; // 达到叶子节点 方案数增1
else{
for(int j = 1; j <= m; j++){ // 试探每一种着色
x[i] = j; // 试探着色j
if(Same(i)) // 可以着色
dfs(i + 1, count);
x[i] = 0; // 回溯
}
}
}

int main(){
int count = 0; // 累计解个数
memset(a, 0, sizeof(a));
memset(x, 0, sizeof(x)); // 初始化
int x, y;
cin >> n >> k >> m;
for(int j = 1; j <= k; j++){
cin >> x >> y; // 输入一条边的两个顶点
a[x][y] = 1;
a[y][x] = 1; // 无向图的边对称
}
dfs(1, count); // 从顶点1开始搜索
if(count > 0)
cout <<"着色方案有" << count;
else
cout << "-1";

return 0;
}

如果要输出所有的着色方案,只需要在找到一个解后输出x中的所有元素即可

#include <bits/stdc++.h>
using namespace std;
#define MAXN 20

// 问题表示
int n, k, m;
int a[MAXN][MAXN];
// 求解结果表示
int x[MAXN]; // x[i]表示顶点i的着色

bool Same(int i){
for(int j = 1; j <= n; j++)
if(a[i][j] == 1 && x[i] == x[j])
return false;
return true;
}

void dispasolution(int &count){
cout << "第" << count << "种着色方案";
for(int j = 1; j <= n; j++)
cout << " " << x[j];
cout << endl;
}

void dfs(int i, int &count){
if(i > n){
count ++; // 达到叶子节点 方案数增1
dispasolution(count);
}
else{
for(int j = 1; j <= m; j++){ // 试探每一种着色
x[i] = j; // 试探着色j
if(Same(i)) // 可以着色
dfs(i + 1, count);
x[i] = 0; // 回溯
}
}
}

int main(){
int count = 0; // 累计解个数
memset(a, 0, sizeof(a));
memset(x, 0, sizeof(x)); // 初始化
int x, y;
cin >> n >> k >> m;
for(int j = 1; j <= k; j++){
cin >> x >> y; // 输入一条边的两个顶点
a[x][y] = 1;
a[y][x] = 1; // 无向图的边对称
}
dfs(1, count); // 从顶点1开始搜索
if(count > 0)
cout <<"着色方案有" << count;
else
cout << "-1";

return 0;
}