图的着色问题
一、题目简述
(1) 图的m-着色判定问题
给定一个无向连通图 G 和 m 种不同的颜色。用这些颜色为图 G 的各顶点着色,每个顶点着一种颜色,是否有一种着色法使 G 中任意相邻的两个顶点着不同颜色?
(2) 图的m-着色优化问题
若一个图最少需要 m 种颜色才能使图中任意相邻的两个顶点着不同颜色,则称这个数 m 为该图的色数。求一个图的最小色数 m 的问题称为m-着色优化问题。
二、算法思想
1. m-着色判定问题
总体思想:通过回溯的方法,不断为每一个节点着色,每个点的颜色由一个数字代表,初始值为1。在对前面 step - 1 个节点都合法的着色之后,开始对第 step 个节点进行着色。如果 n 个点均合法,且颜色数没有达到 m 种,则代表存在一种着色法使 G中任意相邻的两个顶点着不同颜色。
具体步骤:
- 对每个点 step ,有 m 种着色可能性,初始颜色值为1。
- 检查第 step 个节点颜色的可行性,若与某个已着色的点相连且颜色相同,则不选择这种着色方案,并让颜色值加1,继续检查该点下一种颜色的可行性。
- 如果第 step 点颜色值小于等于 m ,且未到达最后一个点,则进行对第 step + 1 点的判断。
- 如果第 step 点颜色值大于 m ,代表该点找不到合适的分配方法。此时算法进行回溯,首先令第 step 节点的颜色值为0,并对第 step - 1 个点的颜色值+1后重新判断。
- 如果找到一种颜色使得第 step 个节点能够着色,说明 m 种颜色的方案是可行的。
- 重复步骤2至5,如果最终 step 为0则代表无解。
2. m-着色优化问题
基于问题1,对于一个无向图 G ,从1开始枚举染色数,上限为顶点数,第一个满足条件的颜色数即为所求解。
三、实现过程(附代码)
1. m-着色判定问题
#include<iostream>
using namespace std;
int color[100]; // 每个点的颜色
int mp[100][100]; // 图的邻接矩阵
int n, m, x; // n顶点,m种颜色方案,x条边
bool check(int step) {
// 判断与step点相邻的点,颜色是否与step点相同,若相同则返回false
for (int i = 1; i <= n; i++) {
if (mp[step][i] == 1 && color[i] == color[step]) {
return false;
}
}
return true;
}
bool Solve(int m) {
// 求解是否可以找到一种可行的染色方案
int step = 1; // step指示当前节点