算法分析与设计实验报告——图的m着色问题
目录:
一、 实验目的
掌握回溯法的基本思想和解决问题的基本步骤,认识回溯法和动态规划、贪心选择的联系与区别,对比解决同一问题的三种算法设计策略的优缺点。
二、实验要求
用c++语言实现用回溯法解决图的m着色问题,分析时间复杂性,体会回溯法解决问题的基本思路和步骤。
三、 实验原理
四、 实验过程(步骤)
见附件一
实验步骤、特点
重要源代码(流操作的部分要醒目的提示并注释)
五、 运行结果
见附件二
六、实验分析与讨论
遇到的问题,及解决方案
七、实验特色与心得
附件一 实验过程(步骤)
#include <bits/stdc++.h>
using namespace std;
class Color {
friend int mColoring(int n, int m, int **a);//声明友元函数
private:
bool OK(int k);//判断此颜色可不可用
void Backtrack(int t);
int n, m, **a, *x;//图的顶点数,可用颜色数,邻接矩阵,目前的解
long sum;//已找到的m着色方案数
};
bool Color::OK(int k) {//当边存在时且和周围的颜色不重时,此颜色可用
for (int j = 1; j <= n; j++)
if ((a[k][j] == 1) && (x[j] == x[k]))
return false;
return true;
}
void Color::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 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() {
int n, e, m;
int ii, jj;
cout << "请依次输入顶点数,可用颜色数,边数;" << endl;
cin >> n >> m >> e;
int **a;
a = new int *[e];
for (int i = 0; i < e; i++) {
a[i] = new int[e];
}
for (int i = 0; i < e; i++)
for (int j = 0; j < e; j++)
a[i][j] = 0;
cout << "请依次输入各个顶点之间的相互关系:" << endl;
for (int i = 0; i < e; i++) {
cin >> ii >> jj;
a[ii][jj] = 1;
a[jj][ii] = 1;
}
cout<<"所有不同的着色法:"<<endl;
int total = mColoring(n, m, a);
cout << "Total = " << total << endl;
return 0;
}
/*
5 4 8
1 3
1 2
1 4
2 3
2 4
2 5
3 4
4 5
*/