m着色问题(回溯算法)

来源:互联网 发布:java 邮件认证 编辑:程序博客网 时间:2024/05/02 06:10


算法思想:将图形转换为无向连通图,若两点之间相邻,则判断颜色,颜色相同则退出,若能到达最后一个点,则说明有一种涂色方案,count便加1.

#include<stdio.h>#define m 4#define n 5int count =0;int mar[n][n] = {{0,1,1,1,0},{1,0,1,1,1},{1,1,0,1,0},{1,1,1,0,1},{0,1,0,1,0}};//0表示不相邻,1表示相邻int color[m];int judge(int t){int i;for(i=0;i<t;i++){if(mar[i][t]==1&&color[i]==color[t])    return 0;}return 1;}void traceback(int t){int i;if(t==n){count++;return ;}for(i=0;i<m;i++){color[t] = i;if(judge(t))   traceback(t+1);}} int main(){    traceback(0);printf("%d",count);return 0;} 
百度百科上的算法较为规整,代码如下:

#include<stdio.h>  int color[100];bool ok(int k,int c[][100])//判断顶点k的着色是否发生冲突{  int i,j;  for(i=1;i<k;i++)  {    if(c[k][i]==1&&color[i]==color[k])      return false;  }  return true;}  void graphcolor(int n,int m,int c[][100]){  int i,k;  for(i=1;i<=n;i++)  color[i]=0;  k=1;  while(k>=1)  {    color[k]=color[k]+1;    while(color[k]<=m)      if(ok(k,c))        break;      else         color[k]=color[k]+1;//搜索下一个颜色      if(color[k]<=m&&k==n)      {        for(i=1;i<=n;i++)           printf("%d",color[i]);        printf("\n");      }      else if(color[k]<=m&&k<n)        k=k+1;//处理下一个顶点      else      {        color[k]=0;        k=k-1;//回溯      }  }}int main(){    int i,j,n,m;    int c[100][100];//存储n个顶点的无向图的数组    printf("输入顶点数n和着色数m:\n");    scanf("%d%d",&n,&m);    printf("输入无向图的邻接矩阵:\n");    for(i=1;i<=n;i++)      for(j=1;j<=n;j++)        scanf("%d",&c[i][j]);    printf("着色所有可能的解:\n");    graphcolor(n,m,c);    return 0;}


原创粉丝点击