图着色问题(回溯法)

问题:
给定 无向连通图G=(V,E) 和 c种不同的颜色,用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果一个图最少需要c种颜色才能使图中每条边连接的2个顶点着不同颜色,则称c为该图的色数。 
著名的 四色定理 就是指每个平面地图都可以只用四种颜色来染色,而且没有两个邻接的区域颜色相同。

求:给定图的顶点v,顶点间的边邻接关系c[][],颜色的数量c,一共有多少种着色方法?

这是一道非常典型的回溯题目。解法与“八皇后问题”一样。在填写每一个顶点的颜色时检查与相邻已填顶点的颜色是否相同。如果不同,则填上;如果相同(冲突),则另选一种;如果已没有颜色可供选择,则回溯到上一顶点。重复这一过程,直到所有顶点的颜色都已填上。

input
5 4 
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

output 
48

è¿éåå¾çæè¿°

对于上面这图,颜色数量为4,顶点数为5,求得的解答树如下:

è¿éåå¾çæè¿°

#include<iostream>
using namespace std;
int c[100][100]; //邻接矩阵
int color[100];  //记录每个顶点的颜色 
int count,m,n; //count记录方案数 n个顶点 m种颜色 
int Check(int k)    //检查第i个顶点的颜色是否满足条件 
{
	for(int i=1;i<=k;i++)
		{
			if(c[k][i]==1&&color[i]==color[k]) //k与i之间相连并且i顶点的颜色与k顶点的颜色相同 
			return 0;	
		}	
	return 1;	
} 

void GraphColor(int step)  
{
	if(step==n+1)  //表示前面所有的顶点颜色都已经填完 
	{
		for(int i=1;i<=n;i++)
			printf("%d ",color[i]);
		count++;
		printf("\n");
		return ;
	}
	else
	{
		for(int i=1;i<=m;i++)
		{
			color[step]=i;   //首先将这个顶点颜色换为i 
			if(Check(step)==1)  //检查是否符合条件 
			{
				GraphColor(step+1); //符合条件则走下一步 
			 
			}		
			color[step]=0;  //回溯 置为0 
		}
	}
}

int main(void)
{
	int a,b;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
				cin>>c[i][j];
		}
 
	GraphColor(1);
	printf("%d",count);
	return 0;	
}

猜你喜欢

转载自blog.csdn.net/a447332241/article/details/87819537
今日推荐