排列树问题
给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色,是否有一种着色法使G中任意相邻的2个顶点着不同颜色?
输出结果:
#include <iostream>
using namespace std;
const int N=5; //
const int M=3;
//5.8节图的m着色问题(回溯法)
/*
0 1 1 1 0
1 0 1 1 1
1 1 0 1 0
0 1 1 0 1
0 1 0 1 0
顶点N=5的图邻接矩阵如上。。。
*/
class Color{
friend int mColoring(int ,int ,int **);
private:
bool Ok(int k); //用于判断某一顶点染色x[k]能否为某一值 i ;
void Backtrack(int t);
int n, //图的顶点数
m, //可用颜色数
**a, //图的邻接矩阵
*x; //当前解
long sum; // 当m为某一确定值时,当前找到的m着色方案数
};
bool Color::Ok(int k){ //检测当前顶点染色x[k]为值 i 能否满足
for(int j=1;j<=n;j++){
if( (a[k][j]==1) &&(x[j]==x[k]) )//相邻且颜色相同,则
return false; //返回false
}
return true;
}
void Color::Backtrack(int t){
if(t>n){
sum++;
cout<<"顶点N="<<N<<"的图着色方案如下"<<endl;
for(int i=1;i<=n;i++)
cout<<x[i]<<" ";
cout<<endl;
}
else
for(int i=1;i<=m;i++){
x[t]=i;
if(Ok(t)) Backtrack(t+1);
//x[t]=0;
}
}
int mColoring(int n,int m,int * * a){
Color X;
X.n=n;
X.m=m;
X.a=a;
X.sum=0;
int *p=new int [n+1];
for(int i=0;i<=n;i++){
p[i]=0;
}
X.x=p;
X.Backtrack(1);
delete []p;
return X.sum;
}
int main()
{
cout<<"输入着色图的邻接矩阵表达式"<<endl;
int **a = new int *[N+1];
for(int i=1;i<=N;i++)
{
a[i] = new int[N+1];
}
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
{
cin>>a[i][j];
}
}
int ans=mColoring(N,M,a);
cout<<"用M="<<M<<"种颜色有"<<ans<<"个染色方案"<<endl;
return 0;
}