当前位置:编程学习 > C/C++ >>

图的m着色问题(回溯)

算法设计例题:图的m着色(回溯)
memory limit: 5000KB    time limit: 2000MS
accept: 8    submit: 14
Description
 
给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的2个顶点着不同颜色,求有多少种方法为图可m着色。
 
Input
 
输入的第一个为测试样例的个数T ( T < 120 ),接下来有T个测试样例。每个测试样例的第一行是顶点数n、边数M和可用颜色数m( n <= 10,M < 100,m <= 7 ),接下来M行,每行两个整数u和v,表示顶点u和v之间有一条边相连。( 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;
}
 
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,