問題:
無向接続グラフ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;
}