problem
- 图的m色优化问题:给定无向连通图G,为图G的各顶点着色, 使图中任2邻接点着不同颜色,问最少需要几种颜色。所需的最少颜色的数目m称为该图的色数。
- 图的m色判定问题: 给定无向连通图G和m种颜色。用这些颜色为图G的各顶点着色.问是否存在着色方法,使得G中任2邻接点有不同颜色。
若图G是可平面图,则它的色数不超过4色(4色定理).
4色定理的应用:在一个平面或球面上的任何地图能够只用4种颜色来着色可使得相邻的国家在地图上着有不同颜色。
Solution
图的m色优化算法可用贪心法来解,其思想是:
任选一顶点着色1,在图中尽可能多的用颜色1着色;
当不能用颜色1着色时,转用颜色2将未着色的顶点尽可能多的着色···
直到所有顶点都被着色停止。
其伪代码如下:
1.for each vertex in G 初始化颜色为0
2.vertex[0]=1//选初始点颜色置为1
3.置颜色种类color=0;
4.循环置所有顶点着色
color++;//取下一颜色
for each vertex in G
if vertex[i]已着色,转下一顶点
else
若该点用color着色与其他邻接点颜色不冲突
vertex[i]=color;
否则不着色
source code
边界条件:函数IsOk时,需要排除着色点和邻接点是同一点的情况。
#include <iostream>
using namespace std;
bool IsOk(int **map, int *vertex, int node, int color, int count)
{
for (int i = 0; i < count; i++)
{
if (map[node][i] == 1 && vertex[i] == color && node != i)//邻接点且着色冲突,且冲突点不是该点本身
return false;
//if (map[node][i] == 1 && vertex[i] == color)也正确,因为判定点和着色点是同一点,着色点此时并未着色不会判false
}
return true;
}
int main(void)
{
freopen("test.in", "r", stdin);
freopen("result.out", "w", stdout);
int count;
cin >> count;
int **map = new int *[count];//邻接矩阵
int *vertex = new int[count];//存储顶点颜色
//申请内存及初始化顶点颜色
for (int i = 0; i < count; i++)
{
map[i] = new int[count];
vertex[i] = 0;
}
//读邻接矩阵数据
for (int i = 0; i < count; i++)
for (int j = 0; j < count; j++)
cin >> map[i][j];
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count; j++)
cout << map[i][j]<< " ";
cout << endl;
}
vertex[0] = 1;//置首节点颜色为1
int color = 0;
int flag = 1;//标志位,是否有节点未被染色
while (flag)//每循环一次用颜色color给尽可能多的结点染色
{
color++;
for (int i = 1; i < count; i++)
{
if (vertex[i] != 0)//已着色
continue;
else//未着色
{
if (IsOk(map, vertex, i, color, count))
vertex[i] = color;
}
}
int k = 0;
for (k = 1; k < count; k++)
{
if (vertex[k] == 0)//有顶点未被着色
break;
}
if (k == count)
flag = 0;
}
cout << "At less" << color << "colors are needed!" << endl;
for (int i = 0; i < count; i++)
cout << "Vertex " << i << ": " << vertex[i] << endl;
return 0;
}
扩展
图着色问题可以用来解一系列带冲突对的划归问题,比如bad horse以及考场安排问题等问题。
考场安排:
设学校共有n门课,需要进行期末考试,因为不少学生不止选修一门课程,所以不能把同一个学生选修的两门课程安排在同一场次进行考试,问学期的期末考试最少需多少场次考完?(提示:如果两门课被同一个同学选上,则表示这两门课的顶点之间存在一条边)。
本问题可转换成是对m-图着色优化算法。将所选的每门课程变成一个结点,若一个同学选了m(1≤m≤n)门课程时,则这m门课程所对应的结点互相用一条边连接起来,及选了A,B,C,D四门课程,则每个课程都发出三条边与其他课程相连。则相邻边的顶点不能着同一种颜色,既不能安排在同一场次考试。本文所求即所有的顶点最少可用多少种颜色来着色。