四色问题的内容是:“任何一张平面地图只用四种颜色就能使具有共同边界的国家着上不同的颜色。 ”用数学语言表示,即“将平面任意地细分为不相重叠的区域,每一个区域总可以用1,2,3,4这四个数字之一来标记,而不会使相邻的两个区域得到相同的数字。
当然这个四色问题有一个限制,四色定理的本质就是在平面或者球面无法构造有五个或者五个以上的两两相连的区域,如果有五个以上两两相连区域,第五个区域至少与一个区域同一种颜色。
首先我们需要建立一个邻接矩阵来存储地图,首先定义结构体存储点以及边,用s来存储每个点的颜色
typedef struct
{
int e_num;//边数
int v_num;//顶点的个数
int a[MAX][MAX];//邻接矩阵
int s[MAX];
}Map;
接下来定义并建立邻接矩阵,输入点的个数还有相连的边数,然后输入相连的边。
void build(Map *M)
{
printf("请输入点的个数\n");
scanf("%d",&M->v_num);
printf("请输入边的个数\n");
scanf("%d",&M->e_num);
for(int i=1;i<=M->v_num;i++){
for(int j=1;j<=M->v_num;j++){
M->a[i][j]=0;
}
}
int x,y;//
printf("请输入边\n");
for(int i=1;i<=M->e_num;i++){
scanf("%d%d",&x,&y);
M->a[x][y]=1;
M->a[y][x]=1;
}
}
接下来定义输出矩阵数据的函数,等染色完成之后,输出每个点的颜色
void pri(Map *M)
{
for(int i=1;i<=M->v_num;i++)
printf("%d ",M->s[i]);
}
接下来是染色函数,从第一个点开始,先把第一个点染成1,,颜色加1,然后看第二个点,然后当颜色小于等于4的时候,并且与跟他相连的数颜色不相同,就将这个点涂成此时col的颜色。
void MapColor(Map *M)
{
int color,area,k;//总共有4种颜色
M->s[1]=1;//第一个区域先着色为颜色1
area=2;//从第二区域开始试探染色
color=1;//从第一种颜色开始试探
while(area<M->v_num+1)//是否全部染色完毕
{
while(color<=4)//确保颜色是四种
{
if(area>=M->v_num+1)
break;
k=0;
while((k<area)&&(M->s[k]*M->a[area][k]!=color))//判断是否重色
k++;
if(k<area)
color++;
else
{
M->s[area]=color;
area++;
color=1;
}
}
if(color>4)//没有找到合适的颜色,需要进行回溯
{
area=area-1;
color=M->s[area]+1;
}
}
}
然后就可以完成四色问题的染色了,主函数在下边,先调用结构体,然后输入地图,然后染色,最后输出每个点的颜色。
int main(){
Map map;
int color[5]={0};
build(&map);
MapColor(&map);
pri(&map);
return 0;
}
所有的代码如下:
#include<bits/stdc++.h>
using namespace std;
#define MAX 100
typedef struct{
int e_num;//边数
int v_num;//顶点的个数
int a[MAX][MAX];//邻接矩阵
int s[MAX];
}Map;
void build(Map *M)
{
printf("请输入点的个数\n");
scanf("%d",&M->v_num);
printf("请输入边的个数\n");
scanf("%d",&M->e_num);
for(int i=1;i<=M->v_num;i++){
for(int j=1;j<=M->v_num;j++){
M->a[i][j]=0;
}
}
int x,y;//
printf("请输入边\n");
for(int i=1;i<=M->e_num;i++){
scanf("%d%d",&x,&y);
M->a[x][y]=1;
M->a[y][x]=1;
}
}
void print_1(Map * M){
for(int i=1;i<=M->v_num;i++){
for(int j=1;j<=M->v_num;j++){
printf("%d ",M->a[i][j]);
}
printf("\n");
}
}
void MapColor(Map *M)
{
int color,area,k;//总共有4种颜色
M->s[1]=1;//第一个区域先着色为颜色1
area=2;//从第二区域开始试探染色
color=1;//从第一种颜色开始试探
while(area<M->v_num+1)//是否全部染色完毕
{
while(color<=4)//确保颜色是四种
{
if(area>=M->v_num+1)
break;
k=0;
while((k<area)&&(M->s[k]*M->a[area][k]!=color))//判断是否重色
k++;
if(k<area)
color++;
else
{
M->s[area]=color;
area++;
color=1;
}
}
if(color>4)//没有找到合适的颜色,需要进行回溯
{
area=area-1;
color=M->s[area]+1;
}
}
}
void pri(Map *M){
for(int i=1;i<=M->v_num;i++)
printf("%d ",M->s[i]);
}
int main(){
Map map;
int color[5]={0};
build(&map);
MapColor(&map);
pri(&map);
return 0;
}
运行结果如下: