图的四色着色(C语言)

2017计算机学硕复试真题

用四种颜色给地图着色,要求相邻块颜色不同,图用邻接矩阵存储,求所有着色方案。

思路:

(草稿)

递归,如用下图,做出邻接矩阵:

map[N][N] = {   0,1,1,0,1,
1,0,1,0,1,
1,1,0,1,0,
0,0,1,0,1,

1,1,0,1,0  }

inputColor(int n,int *color,int col,int sign)是一个递归函数,其中

n表示给第n个点着色 ,col=1表示已经着色,col=0表示未着色 ,sign=0表示未验证,sign=1表示已验证且可行

有以下三种情况:col    sign
   0       0//未着色 ,则着色
   1       0//已着色但未验证 

   1       1//着色且此色可用

故在函数中分三种情况判断:

1、if(col == 0)  //未着色

那么将每一种颜色(颜色用1,2,3,4表示)赋给color[n],并调用递归inputColor(n,color,1,0) 去验证着此色是否可行 

2、if(col==1 && sign==0) //已着色但未验证 

那么验证此位用此色是否行得通,验证方法:在邻接矩阵中找到与此点相邻的点,若这些点的颜色不相邻,则

inputColor(n,color,1,1)//此色可用,sign置为1,若此色不可行,则不作处理,也就不会再有任何操作,也无法打印

3、if(col==1 && sign==1) //着色且此色可用

那么,判断一下此时的n是否是最后一位,若是最后一位即n==N-1,则表示所有位都成功赋予一个颜色,故打印输出

若n<N-1,则去进行处理下一位,inputColor(n+1,color,0,0),当然,下一位的col和sign都是0,回到第一种情况继续处理这一位。

=========================================================================

故如此递归,可以找出所有的着色方案。

代码如下:

#include<stdio.h>
#define N 5
int map[N][N] = {0,1,1,0,1,
    1,0,1,0,1,
    1,1,0,1,0,
    0,0,1,0,1,
    1,1,0,1,0};//五个点,七条边的图,邻接矩阵表示
int main(){
    void inputColor(int n,int *color,int col,int sign);
    int color[5]={0};
    inputColor(0,color,0,0);
    return 0;
}
/**给第n个点着色 ,col=1表示已经着色,col=0表示未着色 ,sign=0表示未验证,sign=1表示已验证且可行 **/
/*
 有以下三种情况:col    sign
 0       0//未着色 ,则着色
 1       0//已着色但未验证
 1       1//着色且此色可用
 当n=N-1,即最后一位时,若此时col==1,sign==1,则可打印输出
 */
void inputColor(int n,int *color,int col,int sign){
    int i;
    for(i=n+1;i<N;i++)//消除之前着色的痕迹
        color[i] = 0;
    if(col == 0){//未着色 ,则着色
        for(i=1;i<=4;i++){//颜色1-4
            color[n] = i;
//            printf("测试:");
//            for(int p = 0;p < N;p++)
//                printf("%d\t",color[p]);
//            printf("测试\n");
            inputColor(n,color,1,0);//验证着此色是否可行
            
        }
    }
    else if(col==1 && sign==0){//已着色但未验证 ,则验证此位
        for(i=0;i<N;i++)
            if(map[n][i]==1 && color[n]==color[i])
                return;
        inputColor(n,color,1,1);//此色可用,sign置为1
    }
    else if(col==1 && sign==1){//着色且此色可用
        if(n<N-1)//进行下一位
            inputColor(n+1,color,0,0);
        else if(n==N-1){//若此位是最后一位,则打印输出
            for(i=0;i<N;i++)
                printf("%d\t",color[i]);
            
            printf("\n");
        }
    }
    
}

 

运行结果:

(部分展示)

 

全部展示:

1	2	3	1	3	
1	2	3	1	4	
1	2	3	2	3	
1	2	3	2	4	
1	2	3	4	3	
1	2	4	1	3	
1	2	4	1	4	
1	2	4	2	3	
1	2	4	2	4	
1	2	4	3	4	
1	3	2	1	2	
1	3	2	1	4	
1	3	2	3	2	
1	3	2	3	4	
1	3	2	4	2	
1	3	4	1	2	
1	3	4	1	4	
1	3	4	2	4	
1	3	4	3	2	
1	3	4	3	4	
1	4	2	1	2	
1	4	2	1	3	
1	4	2	3	2	
1	4	2	4	2	
1	4	2	4	3	
1	4	3	1	2	
1	4	3	1	3	
1	4	3	2	3	
1	4	3	4	2	
1	4	3	4	3	
2	1	3	1	3	
2	1	3	1	4	
2	1	3	2	3	
2	1	3	2	4	
2	1	3	4	3	
2	1	4	1	3	
2	1	4	1	4	
2	1	4	2	3	
2	1	4	2	4	
2	1	4	3	4	
2	3	1	2	1	
2	3	1	2	4	
2	3	1	3	1	
2	3	1	3	4	
2	3	1	4	1	
2	3	4	1	4	
2	3	4	2	1	
2	3	4	2	4	
2	3	4	3	1	
2	3	4	3	4	
2	4	1	2	1	
2	4	1	2	3	
2	4	1	3	1	
2	4	1	4	1	
2	4	1	4	3	
2	4	3	1	3	
2	4	3	2	1	
2	4	3	2	3	
2	4	3	4	1	
2	4	3	4	3	
3	1	2	1	2	
3	1	2	1	4	
3	1	2	3	2	
3	1	2	3	4	
3	1	2	4	2	
3	1	4	1	2	
3	1	4	1	4	
3	1	4	2	4	
3	1	4	3	2	
3	1	4	3	4	
3	2	1	2	1	
3	2	1	2	4	
3	2	1	3	1	
3	2	1	3	4	
3	2	1	4	1	
3	2	4	1	4	
3	2	4	2	1	
3	2	4	2	4	
3	2	4	3	1	
3	2	4	3	4	
3	4	1	2	1	
3	4	1	3	1	
3	4	1	3	2	
3	4	1	4	1	
3	4	1	4	2	
3	4	2	1	2	
3	4	2	3	1	
3	4	2	3	2	
3	4	2	4	1	
3	4	2	4	2	
4	1	2	1	2	
4	1	2	1	3	
4	1	2	3	2	
4	1	2	4	2	
4	1	2	4	3	
4	1	3	1	2	
4	1	3	1	3	
4	1	3	2	3	
4	1	3	4	2	
4	1	3	4	3	
4	2	1	2	1	
4	2	1	2	3	
4	2	1	3	1	
4	2	1	4	1	
4	2	1	4	3	
4	2	3	1	3	
4	2	3	2	1	
4	2	3	2	3	
4	2	3	4	1	
4	2	3	4	3	
4	3	1	2	1	
4	3	1	3	1	
4	3	1	3	2	
4	3	1	4	1	
4	3	1	4	2	
4	3	2	1	2	
4	3	2	3	1	
4	3	2	3	2	
4	3	2	4	1	
4	3	2	4	2	
Program ended with exit code: 0

随机挑选4种方案进行验证:

 

  • 13
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Manigoldo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值