1、图的m着色问题:

 1 /*
 2 *问题描述:给定无向连通图G和m种不同的颜色。用这些颜色为图G的各个顶点着色,每个顶点着一种颜色。是否有一种着色法使G中每条边的两个顶点着不同的颜色。
 3 *           这个问题是图的m可着色判定问题。若一个图最少需要m中颜色才能使图中每条边连接的2个顶点着不同的颜色,则称这个数m为该图的色数。
 4 *算法分析:给定图G=(V,E)和m中颜色,如果这个图不是m可着色,给出否定回答;如果这个图是m可着色的,找出所有不同的着色法。
 5 *           回溯法+子集树
 6 *           问题的解空间可表示为一棵高度为n+1的完全m叉树,解空间树的第i层中每一个结点都有m个儿子,每个儿子相应于x[i]的m个可能的着色之一,第n+1层结点均为叶结点。        
 7 *算法效率:图m可着色问题的解空间树中的内结点个数是m^i之和(i从0到n-1),在最坏的情况下,用ok检查当前扩展结点的每一个儿子所相应的颜色的可用性需耗时O(mn)。
 8            因此回溯总的耗时为mn(m^n-1)/(m-1)=O(nm^n)
 9 *附    注:初始化无向图矩阵的时候对角线赋值为0!!! 
10 *Author:xymaqingxiang
11 *Time:2014--5-22
12 */
13 
14 #include <fstream>
15 #include <iostream>
16 #include <stdlib.h>
17 #include <conio.h>
18 using namespace std;
19 
20 #define MAX_v 50 //定义一个最大顶点个数
21 typedef struct{
22     int a[MAX_v][MAX_v]; //无向图G的邻接矩阵
23     int n; //无向图G的顶点数
24     int m; //无向图G的颜色数
25     int x[50]; //当前解
26     long sum;//当前已找到的可m着色的方案数
27 }MC;
28 
29 void Creat(MC &G);
30 void Backtrack(MC &G,int t);
31 
32 void Creat(MC &G){
33     int i,j;
34     ifstream fin("data.txt");
35     if (!fin)
36     {
37         cout<<"不能打开文件:"<<"data.txt"<<endl;
38         exit(1);
39     }
40     fin>>G.n;
41     fin>>G.m;
42     for (int i=1;i<=G.n;i++)
43         for (int j=1;j<=G.n;j++)
44             fin>>G.a[i][j];
45     for(i=1;i<=G.n;i++) //初始化
46     {
47         G.x[i]=0;
48         G.sum=0;
49     }
50     cout<<"———回溯法求解图的m着色问题———"<<endl;
51     cout<<"输入初始化无向图矩阵为:"<<endl; //初始化
52     for(i=1;i<=G.n;i++)
53     {
54         for(j=1;j<=G.n;j++)
55             cout<<G.a[i][j]<<" ";
56         cout<<endl;
57     }
58     cout<<"输入初始化无向图顶点数为:"<<" "; //初始化
59     cout<<G.n<<endl;
60     cout<<"输入初始化无向图着色数为:"<<" "; //初始化
61     cout<<G.m<<endl;
62 }
63 
64 bool ok(MC &G,int k)
65 {
66     for(int j=1;j<=G.n;j++)
67         if(G.a[k][j]==1&&G.x[j]==G.x[k])    //先后顺序——先判断是否相邻,然后判断颜色是否相同
68             return false;
69     return true;
70 }
71 
72 void Backtrack(MC &G,int t){
73     if (t>G.n){        //output()阶段
74         G.sum++;
75         for (int j=1; j<=G.n; j++)
76             cout<<G.x[j]<<' ';
77         cout<<endl;
78     }
79     else
80     {
81         for(int i=1;i<=G.m;i++)
82         {
83             G.x[t]=i;
84             if(ok(G,t))
85                 Backtrack(G,t+1);
86             G.x[t]=0;    //递归回退时返回上一层,着色赋初值0
87         }
88     }
89 }
90 
91 int main(){
92     MC G;
93     Creat(G);
94     Backtrack(G,1);
95     getch();
96 }
图的m着色问题

相关文章: