问题
解析
可以通过回溯的方法,不断的为每一个节点着色,在前面n-1个节点都合法的着色之后,开始对第n个节点进行着色,这时候枚举可用的m个颜色,通过和第n个节点相邻的节点的颜色,来判断这个颜色是否合法,如果找到那么一种颜色使得第n个节点能够着色,那么说明m种颜色的方案是可行的。
源代码
#include <iostream>
#include <cstdio>
using namespace std;
int n,m;
int a=1,b=1;
int count=0;
int graph[30][30]={0};
int color[30]={0};
bool check(int c)
{
for(int k=1;k<=n;k++)
{
if(graph[c][k]&&color[c]==color[k])
{
return false;
}
}
return true;
}
void backtrack(int cur)
{
if(cur>n)
{
for(int i=1;i<=n;i++)
{
printf("%d ",color[i]);
}
count++;
printf("\n");
}
else
{
for(int i=1;i<=m;i++)
{
color[cur]=i;
if(check(cur))
{
backtrack(cur+1);
}
color[cur]=0;
}
}
}
int main()
{
printf("输入顶点个数和颜色数:");
scanf("%d %d",&n,&m);
printf("输入顶点关心,格式a b,表示a和b相邻,同时为0结束\n");
while(scanf("%d %d",&a,&b)!=EOF&&a!=0&&b!=0)
{
graph[a][b]=1;
graph[b][a]=1;
}
backtrack(1);
printf("Total=%d",count);
return 0;
}
运行结果
复杂度
O(m^n) m为颜色数,n为顶点数