【算法】栈在回溯法中的应用-地图四染色问题

"四染色"问题:用不多于四种颜色对地图着色,使相邻的区域不重色。

算法思想:从第一个区域开始染色,每一个区域依次用颜色1,2,3,4进行试探,如果当前所试探的颜色与周围区域都不同色,则用栈记录该区域色数,否则用下一色数继续试探;如果四种颜色都与相邻区域重色,那么需要退栈,修改栈顶色数,即更改上一区域的颜色继续试探。

数据结构:

  • s[]栈的顺序存储,用于表示区域的染色
  • dist[][]地图邻接矩阵,0表示不邻接,1表示邻接,区域与它自己表示为不邻接

以六区域为例:

/**
* 地图四染色问题
* @author SunShuai
*
*/
#include<stdio.h>
void mapcolor(int dist[6][6], int areanum,int s[6]){
    s[0] = 1;//一号地区涂一号色
    int curarea = 1;//当前应该涂的区域
    int color = 1;//颜色
    int i = 0;
    while (curarea < areanum){//还没涂完
        while (color <= 4 && curarea < areanum){//每种颜色进行试探
            i = 0;
            while ((i < curarea) && (s[i] * dist[curarea][i] != color)){//与当前区域相邻的已染色区域是否有与此种颜色相同的
                i++;
            }
            if (i<curarea){//k<curarea,提前退出循环,说明此种颜色不可用,比对下一种颜色
                color++;
            }
            else{//此种颜色可用
                s[curarea] = color;//当前区域染色
                curarea++;//开始下一区域
                color = 1;//color从一开始
            }
        }
        if (color>4){//color>4说明找不到合适的颜色对当前区域进行染色,回溯,更改上一个区域的颜色,
            curarea--;
            color = s[curarea] + 1;//因为上一个区域已经染色,所以从已染色的下一个颜色开始即可
        }
    }
    
}
void main() {
    int areaNum = 6;//地区数量
    int dist[6][6] = {//邻接矩阵,0表示不邻接
        { 0, 1, 1, 0, 0, 1 },
        { 1, 0, 1, 1, 1, 1 },
        { 1, 1, 0, 1, 0, 0 },
        { 0, 1, 1, 0, 1, 0 },
        { 0, 1, 0, 1, 0, 1 },
        { 1, 1, 0, 0, 1, 0 }
    };
    int s[6];//记录颜色
    mapcolor(dist, areaNum,s);
    for (int o = 0; o < areaNum; o++){
        printf("%d号区域:第%d号颜色\n", o + 1, s[o]);
    }
    system("pause");
}

结果:

同理可计算任意种颜色和任意区域数的颜色填充问题

 

posted @ 2017-06-18 18:23  ♚帅  阅读(3576)  评论(0编辑  收藏  举报