グラフ彩色問題(バックトラッキング法)

問題:
無向接続グラフG =(V、E)とcの異なる色が与えられた場合、これらの色を使用してグラフGの頂点に色を付け、各頂点に色を付けます。グラフの各エッジで接続された2つの頂点の色を変えるために、グラフに少なくともc色が必要な場合、cはグラフの彩色数と呼ばれます。 
有名な4色定理は、すべてのフラットマップを4色でのみ色付けでき、隣接する2つの領域が同じ色になることはないことを意味します。

見つける:グラフの頂点v、頂点c [] []間のエッジ隣接関係、色の数c、色付け方法はいくつありますか?

 

これは非常に典型的なバックトラックの問題です。解決策は「エイトクイーンズ問題」と同じです。各頂点の色を入力するときは、隣接する頂点の色が同じかどうかを確認してください。それらが異なる場合は入力します。同じ(競合)の場合は別の色を選択します。選択する色がない場合は、前の頂点に戻ります。すべての頂点の色が塗りつぶされるまで、このプロセスを繰り返します。

 

入力
54 
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

出力 
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