给定无向连通图G=(V, E)和m种不同的颜色,用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中相邻的两个顶点有不同的颜色?
这个问题是图的m可着色判定问题。若一个图最少需要m种颜色才能使图中每条边连接的两个顶点着不同颜色,则称这个数m为该图的色数。求一个图的色数m的问题称为图的m可着色优化问题。
编程计算:给定图G=(V, E)和m种不同的颜色,找出所有不同的着色法和着色总数。
#include <stdio.h>
#include <stdbool.h>
#define MAX 50
int x[MAX];//存顶点i的着色
int a[MAX][MAX];//领接矩阵,存边
int count=0;//解法
void print();//输出解法
void solve(int i);//着色
bool isS(int i);//判断顶点i与相邻顶点着色是否一样
int n,k,m;//n顶点,k边,m颜色
int main()
{
printf("回溯法-图的m着色问题\n");
printf("请输入顶点,边,颜色个数:\n");
scanf("%d%d%d",&n,&k,&m);
//初始化邻接矩阵
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
a[i][j]=0;
x[i]=0;
}
printf("请输入%d条边:\n",k);
int x,y;//临时存输入
for(int i=1;i<=k;i++)//k条边
{
scanf("%d%d",&x,&y);
a[x][y]=1;
a[y][x]=1;
}
solve(1);//从顶点1开始
printf("共计有%d种解法",count);
return 0;
}
void print()//输出解法
{
printf("第%d种解法:\n",count);
for(int i=1;i<=n;i++)
{
printf("(%d,%d) ",i,x[i]);
}
printf("\n");
}
void solve(int i)//着色
{
if(i>n)//一种解法结束
{
count++;
print();
}
else
{
for(int j=1;j<=m;j++)//m种颜色着色
{
x[i]=j;//试探j能否着色
if(isS(i))
{
solve(i+1);//成功,下一个顶点
}
x[i]=0;//初始化,回溯
}
}
}
bool isS(int i)//判断顶点i是否可以着该色
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==1&&x[i]==x[j])//顶点间有边并且颜色一样
return false;
}
return true;
}