图的m着色问题(回溯)

来源:互联网 发布:东方网络2017分红 编辑:程序博客网 时间:2024/05/02 01:55

算法设计例题:图的m着色(回溯)

memory limit: 5000KB    time limit: 2000MS

accept: 8    submit: 14

Description

给定无向连通图Gm种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的2个顶点着不同颜色,求有多少种方法为图可m着色。

Input

输入的第一个为测试样例的个数( T < 120 ),接下来有T个测试样例。每个测试样例的第一行是顶点数n、边数M和可用颜色数m( n <= 10M < 100m <= 7 ),接下来M行,每行两个整数uv,表示顶点uv之间有一条边相连。( 1 <= u < v <= n )。

Output

对应每个测试样例输出两行,第一行格式为"Case #: W",其中'#'表示第几个测试样例(从1开始计),W为可m着色方案数。

Sample Input

1
5 8 5
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5

Sample Output

Case 1: 360

Author

Eapink



解决方法:

#include<iostream>
using namespace std;
#define N 100
int m,n,M,a[N][N],x[N],textNum;
int static sum=0;


bool ok(int k)
{
for(int j=1;j<=n;j++)
if(a[k][j]&&(x[j]==x[k]))
return false;
return true;
}


void backtrack(int t)
{
  if(t>n)
  {
 sum++;
// 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 main()
{
    int i,j,z=1;
cin>>textNum;                 //输入测试个数
while(textNum>0)
{
        cin>>n;                    //输入顶点个数
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=0;
        cin>>M>>m;                 //输入边的个数、可用颜色数
for(int k=1;k<=M;k++)      //生成图的邻接矩阵
{
cin>>i>>j;
a[i][j]=1;
a[j][i]=1;
}
/* for(i=1;i<=n;i++){
for(j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<endl;}*/
for(i=0;i<=n;i++)
x[i]=0;
        backtrack(1);
        cout<<"Case "<<z<<": "<<sum<<endl;
    sum=0;


textNum--;
z++;
}


return 0;
}