中国地图着色问题:在中国地图中对各省进行着色,相邻省所使用的颜色不同,并保证所用颜色最少。
解决中国地图着色问题,有两个方面的要求,一个是相邻省所使用的颜色不同,另一个是所用颜色最少。实现这两个要求的思路如下:
一、为保证相邻省所使用的颜色不同,在给每个省上色前排除其相邻省已用颜色,使用剩下的可用颜色中的第一种颜色进行着色,上色后也将该颜色排除,避免在回溯时再次使用该颜色,且回溯时会初始化部分或全部的省份颜色和颜色数组。
具体实现方法:设置一个颜色数组存放各省可用颜色,在上色前将相邻省已用颜色的颜色值赋值为0,上色时使用第一个不为0 的颜色值,上色后将该颜色值也赋值为0。
二、为保证所用颜色最少,每次用不同的省作为第一个着色省份开始着色。首先使用两种颜色,若在着色时失败则增加到三种颜色进行着色,若三种颜色着色也失败则增加到四种颜色,直至用最少的颜色着色成功。着色成功后用下一个省份作为第一个着色省份开始着色,重复上述步骤,直至用所有省份作为第一个着色省份开始着色,并用最少的颜色成功着色,再通过比较各个省份作为第一个着色省份开始着色,着色成功时所需要的最少颜色数,得出着色所需最少颜色数。
具体实现方法:用循环双链表连接邻接表通过双重循环和回溯来实现。在某个省份上色使用颜色值超过最大可用颜色值时回溯到上一个省份的上色中,上一个省份选择其他可用颜色,继续内层循环。当回溯使第一个省份上色使用颜色超过当前最大可用颜色时,将最大可用颜色加1,重新开始内层循环。当着色成功后内层循环结束,用该省作为第一个着色省份所用着色的颜色数,与最少着色颜色数比较并保存较小值,接着外层循环进入到下一步用另一个省份作为第一个着色省份,直至外层循环结束得出最少着色颜色数。
源程序如下,可在Dev C++下运行,在VS中可能需稍作修改。
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include "string.h"
#include<time.h>
typedef struct ArcNode{
int apn; //相邻省序号
struct ArcNode *nextarc;//指向下一个结点
}ArcNode;
typedef struct VNode{
char name[6]; //省份名字
int color; //省份颜色
int number; //省份序号
ArcNode *firstarc; //头节点
}VNode;
typedef struct DNode //定义双链表结点类型
{
struct VNode *data;
struct DNode *prior; //指向前驱结点
struct DNode *next; //指向后继结点
}DLinkNode;
ArcNode *node[145],*p;
VNode province[35];
int color[35][5]; //颜色数组
void Intput(VNode*province,ArcNode*node[]); //输入中国地图信息
void Initialization(VNode*province); //初始化各省颜色及颜色数组
void Painting(VNode*province,ArcNode*p,int i); //上色
void Setcolor(int i); //设置输出颜色
void Output(VNode*province,ArcNode*p); //输出信息
void Find(DLinkNode *&L,VNode*province,ArcNode*p); //求最少着色颜色数
void CreateListR(DLinkNode *&L,VNode*province,int n); //尾插法建双链表