1. 程式人生 > >中國地圖的四色問題

中國地圖的四色問題

首先,該問題需要運用到資料結構無向圖的相關知識。

將中國地圖(不包含臺灣、海南)看做是一張無向圖,相鄰接的省份用直線相互連線,就能夠得到一張無向圖。


用鄰接矩陣的方法來儲存該無向圖,相鄰結點對應數字1,不相鄰結點對應數字0。

.然後,在主函式中從一種顏色開始迴圈,直到滿足能用這幾種顏色填滿地圖(方法數不為0)。

for(i=1;i<100;i++)
{
dfs(1,i);
if(WayNumber!=0){
printf("填滿地圖至少需要%d種顏色\n",i);
break;
}


用遞迴的方法進行廣度遍歷,用數字1,2,3,4......表示顏色,構造一個用於存放顏色的陣列area[],

當鄰接矩陣Map[i][j]等於1時,對應的area[i]和area[j]的值不能相同,通過for迴圈從顏色1開始,

不斷進行上色,最終判斷全部結點都已染色時,方法數加1。

for(i=0;i<ColorNumber;i++)
{
int biaoshi=1;

for(j=1;j<youbiao;j++)
{
if((Map[j][youbiao]==1)&&(area[j]==i)) 
{
biaoshi=0;
break;
}
}
if(biaoshi)
{
area[youbiao]=i;  //遊標所在省份染為第i種顏色
}       



源程式:

#include <stdio.h>

#include <stdlib.h>
#define AREANUMBER 27


int WayNumber=0;  //方法數
int Map[AREANUMBER+1][AREANUMBER+1];
int area[AREANUMBER+1];


/*typedef struct ArcNode{
int number;  //和該頂點鄰接的頂點編號
struct ArcNode *next;  //頂點指向的下一個位置
}ArcNode;


typedef struct{
int data;  //對應頂點的編號
ArcNode *firstnext;  //和該頂點鄰接的第一個頂點編號
}ArcList;


typedef ArcList Map[AREANUMBER];  //地圖的鄰接表陣列
*/


void CreateMap(int Map[AREANUMBER+1][AREANUMBER+1]);  //地圖建立函式
void dfs(int now,int ColorNumber);  //深度遍歷函式


void main(){
int i,j;
for(i=1;i<=AREANUMBER;i++)
for(j=1;j<=AREANUMBER;j++)
Map[i][j]=0;
CreateMap(Map);
for(i=1;i<100;i++)
{
dfs(1,i);
if(WayNumber!=0){
printf("填滿地圖至少需要%d種顏色\n",i);
break;
}
}
}


void CreateMap(int Map[AREANUMBER+1][AREANUMBER+1]){
/*ArcNode *p,*q;


GL[1].data=1;


p=(ArcNode *)malloc(sizeof(ArcNode));
p->number=3;
p=GL[1].firstnext;


q=(ArcNode *)malloc(sizeof(ArcNode));
q->number=4;
q=p->next;


p=(ArcNode *)malloc(sizeof(ArcNode));
p->number=2;
p=q->next;
*/
Map[1][2]=Map[2][1]=1;  //新疆
Map[1][3]=Map[3][1]=1;
Map[1][4]=Map[4][1]=1;


Map[2][4]=Map[4][2]=1;  //西藏
Map[2][5]=Map[5][2]=1;
Map[2][10]=Map[10][2]=1;


Map[3][4]=Map[4][3]=1;  //甘肅
Map[3][5]=Map[5][3]=1;
Map[3][7]=Map[7][3]=1;
Map[3][8]=Map[8][3]=1;
Map[3][12]=Map[12][3]=1;


Map[4][5]=Map[5][4]=1;  //青海


Map[5][6]=Map[6][5]=1;  //四川
Map[5][8]=Map[8][5]=1;
Map[5][9]=Map[9][5]=1;
Map[5][10]=Map[10][5]=1;


Map[6][8]=Map[8][6]=1;  //重慶
Map[6][9]=Map[9][6]=1;
Map[6][13]=Map[13][6]=1;
Map[6][14]=Map[14][6]=1;


Map[7][8]=Map[8][7]=1;  //寧夏
Map[7][12]=Map[12][7]=1;


Map[8][12]=Map[12][8]=1;  //陝西
Map[8][14]=Map[14][8]=1;
Map[8][15]=Map[15][8]=1;
Map[8][16]=Map[16][8]=1;


Map[9][10]=Map[10][9]=1;  //貴州
Map[9][11]=Map[11][9]=1;
Map[9][13]=Map[13][9]=1;


Map[10][11]=Map[11][10]=1;  //雲南


Map[11][26]=Map[26][11]=1;  //廣西
Map[11][13]=Map[13][11]=1;


Map[12][15]=Map[15][12]=1;  //內蒙古
Map[12][17]=Map[17][12]=1;
Map[12][18]=Map[18][12]=1;
Map[12][19]=Map[19][12]=1;
Map[12][20]=Map[20][12]=1;


Map[13][14]=Map[14][13]=1;  //湖南
Map[13][24]=Map[24][13]=1;
Map[13][26]=Map[26][13]=1;


Map[14][16]=Map[16][14]=1;  //湖北
Map[14][22]=Map[22][14]=1;
Map[14][24]=Map[24][14]=1;


Map[15][16]=Map[16][15]=1;  //山西
Map[15][17]=Map[17][15]=1;


Map[16][17]=Map[17][16]=1;  //河南
Map[16][21]=Map[21][16]=1;
Map[16][22]=Map[22][16]=1;


Map[17][20]=Map[20][17]=1;  //河北
Map[17][21]=Map[21][17]=1;

Map[18][19]=Map[19][18]=1;  //黑龍江


Map[19][20]=Map[20][19]=1;  //吉林
                                //遼寧
Map[21][23]=Map[23][21]=1;  //山東


Map[22][23]=Map[23][22]=1;  //安徽
Map[22][24]=Map[24][22]=1;
Map[22][25]=Map[25][22]=1;


Map[23][25]=Map[25][23]=1;  //江蘇


Map[24][25]=Map[25][24]=1;  //江西
Map[24][26]=Map[26][24]=1;
Map[24][27]=Map[27][24]=1;


Map[25][27]=Map[27][25]=1;  //浙江


Map[26][27]=Map[27][26]=1;  //廣東
                           //福建
}


void dfs(int youbiao,int ColorNumber){
int i,j,k;
for(i=0;i<ColorNumber;i++)
{
int biaoshi=1;

for(j=1;j<youbiao;j++)
{
if((Map[j][youbiao]==1)&&(area[j]==i))  //遊標所在省與j省鄰接,且j省被染為第i種顏色
{
biaoshi=0;
break;
}
}

if(biaoshi)
{


area[youbiao]=i;  //遊標所在省份染為第i種顏色


if(youbiao==AREANUMBER)  //全部結點都已染色
WayNumber++;  //方法數+1
else
dfs(youbiao+1,ColorNumber);  //下一個省份染色


}       

}