用回溯法求解图的m着色问题

合集下载

回溯法实验(图的m着色问题)

回溯法实验(图的m着色问题)

算法分析与设计实验报告第六次附加实验cout<<endl;}elsefor(int i=1;i<=m;i++){x[t]=i;if(ok(t)) Backtrack(t+1);//回溯,继续寻找下一层x[t]=0;//回到最初状态,使x[1]继续尝试其他填色的可能解}}测试结果当输入图如下时:结果如下:12435只要输入边即可当输入的图如下时:结果如下:附录:完整代码(回溯法)//图的m着色问题回溯法求解#include<iostream>using namespace std;class Color{friend void mColoring(int,int,int **);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++; //可行解+1cout<<"着色: ";for(int i=1;i<=n;i++) //输出可行解方案cout<<x[i]<<" ";cout<<endl;}elsefor(int i=1;i<=m;i++){x[t]=i;if(ok(t)) Backtrack(t+1);//回溯,继续寻找下一层x[t]=0;//回到最初状态,使x[1]继续尝试其他填色的可能解 }}void mColoring(int n,int m,int **a){Color X;//初始化XX.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;cout<<"顶点: ";for(int i=1;i<=n;i++) //用于输出结果cout<<i<<" " ;cout<<endl;X.Backtrack(1); //从顶点1开始回溯delete []p;cout<<"解法个数:"<<X.sum<<endl;}int main(){int n;int m;cout<<"please input number of node:";cin>>n;cout<<"please input number of color:";cin>>m;int **a=new int*[n+1];for(int i=0;i<=n;i++)a[i]=new int[n+1];for(int i=0;i<=n;i++) //利用抽象图实现图的邻接矩阵for(int j=0;j<=n;j++)a[i][j]=0;int edge;cout<<"please input adjacent edge number:";cin>>edge;int v,w;cout<<"please inout adjacent edge:"<<endl; //只要输入边即可for(int i=0;i<edge;i++){cin>>v>>w; //由于是无向图,所以对应的邻接矩阵对应的边都有,即v->m,m->v都有边a[v][w]=1;a[w][v]=1;}mColoring(n,m,a);system("pause");return 0;}。

图的着色问题--C++实现(含详细注释)

图的着色问题--C++实现(含详细注释)

图的着色问题一、题目简述(1) 图的m-着色判定问题给定一个无向连通图 G 和 m 种不同的颜色。

用这些颜色为图 G 的各顶点着色,每个顶点着一种颜色,是否有一种着色法使 G 中任意相邻的两个顶点着不同颜色?(2) 图的m-着色优化问题若一个图最少需要 m 种颜色才能使图中任意相邻的两个顶点着不同颜色,则称这个数 m 为该图的色数。

求一个图的最小色数 m 的问题称为m-着色优化问题。

二、算法思想1. m-着色判定问题总体思想:通过回溯的方法,不断为每一个节点着色,每个点的颜色由一个数字代表,初始值为1。

在对前面 step - 1 个节点都合法的着色之后,开始对第 step 个节点进行着色。

如果 n 个点均合法,且颜色数没有达到 m 种,则代表存在一种着色法使 G中任意相邻的两个顶点着不同颜色。

具体步骤:1. 对每个点 step ,有 m 种着色可能性,初始颜色值为1。

2. 检查第 step 个节点颜色的可行性,若与某个已着色的点相连且颜色相同,则不选择这种着色方案,并让颜色值加1,继续检查该点下一种颜色的可行性。

3. 如果第 step 点颜色值小于等于 m ,且未到达最后一个点,则进行对第 step + 1 点的判断。

4. 如果第 step 点颜色值大于 m ,代表该点找不到合适的分配方法。

此时算法进行回溯,首先令第 step 节点的颜色值为0,并对第 step - 1 个点的颜色值+1后重新判断。

5. 如果找到一种颜色使得第 step 个节点能够着色,说明 m 种颜色的方案是可行的。

6. 重复步骤2至5,如果最终 step 为0则代表无解。

2. m-着色优化问题基于问题1,对于一个无向图 G ,从1开始枚举染色数,上限为顶点数,第一个满足条件的颜色数即为所求解。

三、实现过程(附代码)1. m-着色判定问题#include<iostream>using namespace std;int color[100]; // 每个点的颜色int mp[100][100]; // 图的邻接矩阵int n, m, x; // n顶点,m种颜色方案,x条边bool check(int step) {// 判断与step点相邻的点,颜色是否与step点相同,若相同则返回falsefor (int i=1; i<=n; i++) {if (mp[step][i] ==1&&color[i] ==color[step]) {return false;}}return true;}bool Solve(int m) {// 求解是否可以找到一种可行的染色方案int step=1; // step指示当前节点while (step>=1) {color[step] +=1; // 假定颜色值从1开始,若为回溯,选择下一种方案while (color[step] <=m) { // 按照问题条件选择第step点颜色if (check(step)) {break;} else {color[step]++; // 搜索下一个颜色}}if (color[step] <=m&&step==n) { // 如果找完n个点,且染色方法小于等于m种 return true;} else if (color[step] <=m&&step<n) {step++; // 求解下一个顶点} else { // 如果染色数大于m个,回溯color[step] =0; // 回溯,该点找不到合适的分配方法,对上一点进行分析step--;}}// 如果step退到0,则代表无解return false;}int main() {int i, j;bool ans=false;cout<<"输入顶点数n和着色数m"<<endl;cin>>n>>m;cout<<"输入边数"<<endl;cin>>x;cout<<"具体输入每条边"<<endl;for (int p=0; p<x; p++) { // 以无向邻接矩阵存储边cin>>i>>j;mp[i][j] =1;mp[j][i] =1;}if (Solve(m)) {cout<<"有解";} else {cout<<"无解";}return0;}2. m-着色优化问题#include<iostream>using namespace std;int color[100]; // 每个点的颜色int mp[100][100]; // 图的邻接矩阵int n, m, x; // n顶点,m种颜色方案,x条边bool check(int step) {// 判断与step点相邻的点,颜色是否与step点相同,若相同则返回falsefor (int i=1; i<=n; i++) {if (mp[step][i] ==1&&color[i] ==color[step]) {return false;}}return true;}bool Solve(int m) {// 求解是否可以找到一种可行的染色方案int step=1; // step指示当前节点while (step>=1) {color[step] +=1; // 假定颜色值从1开始,若为回溯,选择下一种方案while (color[step] <=m) { // 按照问题条件选择第step点颜色if (check(step)) {break;} else {color[step]++; // 搜索下一个颜色}}if (color[step] <=m&&step==n) { // 如果找完n个点,且染色方法小于等于m种 return true;} else if (color[step] <=m&&step<n) {step++; // 求解下一个顶点} else { // 如果染色数大于m个,回溯color[step] =0; // 回溯,该点找不到合适的分配方法,对上一点进行分析step--;}}// 如果step退到0,则代表无解return false;}int main() {int i, j;bool ans=false;cout<<"输入顶点数n"<<endl;cin>>n;cout<<"输入边数"<<endl;cin>>x;cout<<"具体输入每条边"<<endl;for (int p=0; p<x; p++) { // 以无向图邻接矩阵存储边 cin>>i>>j;mp[i][j] =1;mp[j][i] =1;}for (m=1; m<=n; m++) { // 从小到大枚举着色数mif (Solve(m)) { // 如果有解,输出答案并跳出循环cout<<"最小色数m为 "<<m;break;}}return0;}四、结果及分析问题1测试用例:问题2测试用例:经检验,最少着色数的范围为2-4,意味着使 G 中任意相邻的两个顶点着不同颜色最多需要4种颜色。

涂色问题的常见解法及策略

涂色问题的常见解法及策略

涂色问题的常见解法及策略涂色问题是在给定一定数量的图形或区域的情况下,选择不同的颜色对它们进行涂色,使得相邻的区域具有不同的颜色。

这个问题在计算机图像处理、地图着色、图论等领域都有广泛的应用。

本文将介绍常见的涂色问题解法及策略。

1. 回溯法回溯法是一种常见的解决涂色问题的策略。

其基本思想是尝试在每个区域上涂上一种颜色,并检查该颜色是否符合要求。

如果符合要求,则继续涂色下一个区域;如果不符合要求,则回溯到上一个区域重新选择颜色。

回溯法的算法步骤如下:1.选择一个起始区域。

2.在该区域上选择一种颜色,并检查是否与相邻区域的颜色冲突。

3.如果颜色冲突,则选择另一种颜色,并重新检查。

4.如果所有颜色都冲突,则回溯到上一个区域重新选择颜色。

5.重复步骤2-4,直到所有区域都被涂色。

回溯法的优点是简单易懂,容易实现。

但对于复杂的问题,可能会产生大量的重复计算,效率较低。

为了提高效率,可以采用剪枝或启发式搜索等技巧进行优化。

2. 图着色算法涂色问题可以看作是图着色问题的特例,其中每个区域可以看作是一个节点,相邻的区域之间有一条边。

因此,可以借用图着色算法来解决涂色问题。

图着色算法的基本思想是为每个节点选择一个颜色,并确保相邻节点具有不同的颜色。

常见的图着色算法有贪心算法、回溯法、禁忌搜索等。

其中,贪心算法是一种简单且高效的图着色算法。

其基本思想是每次选择一个颜色,并将其分配给当前节点,然后继续处理下一个节点。

在选择颜色时,优先选择与当前节点相邻节点颜色不同的颜色。

贪心算法的流程如下:1.对节点进行排序,按照节点的度从大到小排序。

2.依次处理每个节点,选择一个颜色,并将其分配给当前节点。

3.检查相邻节点的颜色,如果与当前节点的颜色相同,则选择另一种颜色,并重新检查。

4.重复步骤2-3,直到所有节点都被着色。

贪心算法的优点是简单高效,适用于大规模的问题。

然而,由于贪心算法的局部最优性,可能无法得到全局最优解。

3. 深度优先搜索深度优先搜索是一种常见的解决涂色问题的策略。

算法设计与分析复习题目及答案

算法设计与分析复习题目及答案

一。

选择题1、二分搜索算法是利用( A )实现的算法。

A、分治策略B、动态规划法C、贪心法D、回溯法2、下列不是动态规划算法基本步骤的是( B )。

A、找出最优解的性质B、构造最优解C、算出最优解D、定义最优解3、最大效益优先是( A )的一搜索方式。

A、分支界限法B、动态规划法C、贪心法D、回溯法4、在下列算法中有时找不到问题解的是( B )。

A、蒙特卡罗算法B、拉斯维加斯算法C、舍伍德算法D、数值概率算法5. 回溯法解旅行售货员问题时的解空间树是( B )。

A、子集树B、排列树C、深度优先生成树D、广度优先生成树6.下列算法中通常以自底向上的方式求解最优解的是( B )。

A、备忘录法B、动态规划法C、贪心法D、回溯法7、衡量一个算法好坏的标准是(C )。

A 运行速度快B 占用空间少C 时间复杂度低D 代码短8、以下不可以使用分治法求解的是(D )。

A 棋盘覆盖问题B 选择问题C 归并排序D 0/1背包问题9. 实现循环赛日程表利用的算法是( A )。

A、分治策略B、动态规划法C、贪心法D、回溯法10、下列随机算法中运行时有时候成功有时候失败的是(C )A 数值概率算法B 舍伍德算法C 拉斯维加斯算法D 蒙特卡罗算法11.下面不是分支界限法搜索方式的是( D )。

A、广度优先B、最小耗费优先C、最大效益优先D、深度优先12.下列算法中通常以深度优先方式系统搜索问题解的是( D )。

A、备忘录法B、动态规划法C、贪心法D、回溯法13.备忘录方法是那种算法的变形。

( B )A、分治法B、动态规划法C、贪心法D、回溯法14.哈弗曼编码的贪心算法所需的计算时间为( B )。

A、O(n2n)B、O(nlogn)C、O(2n)D、O(n)15.分支限界法解最大团问题时,活结点表的组织形式是( B )。

A、最小堆B、最大堆C、栈D、数组16.最长公共子序列算法利用的算法是( B )。

A、分支界限法B、动态规划法C、贪心法D、回溯法17.实现棋盘覆盖算法利用的算法是( A )。

图的着色问题

图的着色问题

问题来源
图的着色
通常所说的着色问题是指下述两类问题: 通常所说的着色问题是指下述两类问题: 1.给定无环图G=(V,E),用m种颜色为图中 的每条边着色,要求每条边着一种颜色, 的每条边着色,要求每条边着一种颜色,并 使相邻两条边有着不同的颜色, 使相邻两条边有着不同的颜色,这个问题称 为图的边着色问题。 为图的边着色问题。 2.给定无向图G=(V,E),用m种颜色为图中 的每个顶点着色,要求每个顶点着一种颜色, 的每个顶点着色,要求每个顶点着一种颜色, 并使相邻两顶点之间有着不同的颜色, 并使相邻两顶点之间有着不同的颜色,这个 问题称为图的顶着色问题。 问题称为图的顶着色问题。
化简得
( a + bd )(b + aceg )(c + bdef )( d + aceg )(e + bcdf )( f + ceg )( g + bdf )
求极小覆盖法- 求极小覆盖法-布尔代数法
Step3:从中挑选所用极大独立集个数最小者, Step3:从中挑选所用极大独立集个数最小者, 即为X 即为X(G) 但上述子集的颜色数都不是X ),正确的应 但上述子集的颜色数都不是X(G),正确的应 该是X =3,该子集为: {b,d,f}中的 该是X(G)=3,该子集为:给{b,d,f}中的 b,d,f涂颜色 涂颜色1 {a,e,g}中a,e,g涂颜色 涂颜色2 b,d,f涂颜色1,为{a,e,g}中a,e,g涂颜色2为 {a,c,g}中的 涂颜色3 中的c {a,c,g}中的c涂颜色3。 由此可见, 由此可见,求色数其需要求极大独立集以 及一切若干极大独立集的和含所有顶点的子 对于大图, 集,对于大图,因为图计算量过大而成为实 际上难以凑效的算法,所以不是一个好算法, 际上难以凑效的算法,所以不是一个好算法, 一般我们采用贪心法等近似算法来求解 。

0030算法笔记——最大团问题和图的m着色问题

0030算法笔记——最大团问题和图的m着色问题
// 计算最大团 void Clique::Backtrack(int i) { 3if (i > n) // 到达叶结点 3{ 33for (int j = 1; j <= n; j++) 33{ 333bestx[j] = x[j]; 333cout<<x[j]<<" "; 33} 33cout<<endl; 33bestn = cn; 33return; 3} 3// 检查顶点 i 与当前团的连接 int OK = 1; 3for (int j = 1; j < i; j++) 3if (x[j] && a[i][j] == 0) 3{ 33// i与j不相连 33OK = 0; 33break; 3}
3if (OK)// 进入左子树 3{ 33x[i] = 1; 33cn++; 33Backtrack(i+1); 33x[i] = 0; 33cn--; 3}
if (cn + n - i >= bestn)// 进入右子树 3{ 33x[i] = 0; 33Backtrack(i+1); 3} }
3333 如果U∈V且对任意u,v∈U有(u, v)不属于E,则称U是G的空子图。G的空子图U是G的独立集当且仅当U不包 含在G的更大的空子图中。G的最大独立集是G中所含顶点数最多的独立集。
3333 对于任一无向图G=(V, E),其补图G'=(V', E')定义为:V'=V,且(u, v)∈E'当且仅当(u, v)∈E。 3333 如果U是G的完全子图,则它也是G'的空子图,反之亦然。因此,G的团与G'的独立集之间存在一一对应的 关系。特殊地,U是G的最大团当且仅当U是G'的最大独立集。

深度优先搜索与回溯算法

深度优先搜索与回溯算法

8、字符序列(characts) 【问题描述】 从三个元素的集合[A,B,C]中选取元素生成一个N个字符组成的序列,使 得没有两个相邻字的子序列(子序列长度=2)相同。例:N = 5时ABCBA是合 格的,而序列ABCBC与ABABC是不合格的,因为其中子序列BC,AB是相同的。 对于由键盘输入的N(1<=N<=12),求出满足条件的N个字符的所有序列和其 总数。 【输入样例】 4 【输出样例】
72
•9、试卷批分(grade) •【问题描述】
•某学校进行了一次英语考试,共有10道是非题,每题为10分,解答用1表示“是”, 用0表示“非”的方式。但老师批完卷后,发现漏批了一张试卷,而且标准答案也丢 失了,手头只剩下了3张标有分数的试卷。
•试卷一:① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩
•0 0 1 0 1 0 0 1 0 0 得分:70
【例6】数的划分(NOIP2001) 【问题描述】 将整数n分成k份,且每份不能为空,任意两种分法不能相同 (不考虑顺序)。例如:n=7,k=3,下面三种分法被认为是相同的。 • 1,1,5; 1,5,1; 5,1,1; • 问有多少种不同的分法。 • 【输入格式】 • n,k (6<n≤200,2≤k≤6) • 【输出格式】 • 一个整数,即不同的分法。 • 【输入样例】 • 7 3 • 【输出样例】 • 4 { 4种分法为:1,1,5;1,2,4;1,3,3; 2,2,3 说明部分不必输出 }
【课堂练习】
1、输出自然数1到n所有不重复的排列,即n的全排列。 【参考过程】 int Search(int i) { Int j; for (j=1;j<=n;j++) if (b[j]) { a[i]=j; b[j]=false; if (I<n) Search(i+1); else print(); b[j]=true; } }

回溯问题:m点着色、n皇后、tsp递归迭代算法

回溯问题:m点着色、n皇后、tsp递归迭代算法

m着色回溯法递归//输入n为顶点个数,颜色数m,图的邻接矩阵c[][]//输出n个顶点的着色x[]//递归方法求解#include <iostream>using namespace std;bool c[6][6];int x[6];int m=3;int n=5;bool ok(int k) //判断对顶点k着色以后是否合法着色{int i;for(i = 1; i < k; i++)if((c[k][i]==1 && x[k] ==x[i]))return false;return true;}void output(int x[]){cout<<"The feasibleresult is:"<<endl;for(int i=1;i<=n;i++)c out<<x[i]<<' ';cout<<endl;return;}void backtrack (int t){if (t>n) output(x);elsefor (int i=1;i<=m;i++) {x[t]=i;if (ok(t)) backtrack(t+1);x[t]=0;}}int main(){int i, j;for(i = 1; i < 5; i++)for(j = 1; j < 5;j++)c[i][j] = false;c[1][2] = true;c[1][3] = true;c[2][3] = true;c[2][4] = true;c[2][5] = true;c[3][5] = true;c[4][5] = true;c[2][1] = true;c[3][1] = true;c[3][2] = true;c[4][2] = true;c[5][2] = true;c[5][3] = true;c[5][4] = true;backtrack(1);cout << endl;return 0;}m着色回溯法迭代//输入n为顶点个数,颜色数m,图的邻接矩阵c[][]//输出n个顶点的着色x[]//第一个结点也可以有m种着色方案#include <iostream>using namespace std;bool c[6][6];int x[6];int m=3;int n=5;bool ok(int k) //判断对顶点k着色以后是否合法着色{int i;for(i = 1; i < k; i++)if((c[k][i]==1 && x[k] ==x[i]))return false;return true;}void m_coloring(int n, int m){int i, k;for(i = 1; i <= n; i++)x[i] = 0;k =1;while(k >=1){x[k]++;while(x[k] <= m)if( ok(k)==1) break;else x[k]++;if(x[k] <= m &&k==n){for(i=1;i<=n;i++)cout<<x[i]<<" ";cout<<endl;k--;//return;如果只需要一个解可以将上两句去掉,加入返回语句}else if(x[k]<=m&&k<n)k++;else{x[k]=0;k--;}}}int main(){int i, j;for(i = 1; i < 5; i++)for(j = 1; j < 5;j++)c[i][j] = false;c[1][2] = true;c[1][3] = true;c[2][3] = true;c[2][4] = true;c[2][5] = true;c[3][5] = true;c[4][5] = true;c[2][1] = true;c[3][1] = true;c[3][2] = true;c[4][2] = true;c[5][2] = true;c[5][3] = true;c[5][4] = true;m_coloring(5, 3);cout << endl;return 0;}//递归方法求解n皇后问题#include <iostream>using namespace std;#define Q_num 4int x[Q_num]; //存放每行棋子位置int number=0; //存放棋盘解的个数void output(int x[]){cout<<"棋盘放置位置如图:"<<endl;for(inti=1;i<=Q_num;i++){for(intj=1;j<=Q_num;j++){if(j==x[i])printf("%3d",x[i]);elseprintf("%3d",0);}cout<<endl;}cout<<endl;}bool Place(int k) //考察皇后k放置在x[k]列是否发生冲突{for (int i=1; i<k; i++)i f (x[k]==x[i] ||abs(k-i)==abs(x[k]-x[i]))return false;r eturn true;}int Queue_backtrack(int t){if (t>Q_num) {number++;output(x);}elsefor (inti=1;i<=Q_num;i++) {x[t]=i;if (x[t] <= Q_num&& Place(t))Queue_backtrack(t+1);x[t]=0;}returnnumber;}int main(){int i;for(i = 1; i <=Q_num;i++)x[i] = 0;cout<<"共有解:"<<Queue_backtrack(1)<<"个"<<endl;cout << endl;return 0;}//回溯法迭代求解n皇后问题#include <iostream>using namespace std;#define Q_num 8int x[Q_num]; //存放每行棋子位置int number=0; //存放棋盘解的个数void output(int x[]){for(inti=1;i<=Q_num;i++){for(intj=1;j<=Q_num;j++){if(j==x[i])printf("%3d",x[i]);elseprintf("%3d",0);}cout<<endl;}cout<<endl;return;}bool Place(int k) //考察皇后k放置在x[k]列是否发生冲突{for (int i=1; i<k; i++)i f (x[k]==x[i] ||abs(k-i)==abs(x[k]-x[i]))return false;r eturn true;}int Queue(int n){int i, k;for(i =0; i <= n; i++)x[i] = 0;k =1;while(k >=1){x[k]++;while(x[k] <= n&& !Place(k))x[k]++;i f(x[k] <= n &&k==n){number++;cout<<"棋盘放置具体位置如图:"<<endl<<endl;output(x);//return;如果只需要一个解}e lse if (x[k]<=n&& k<n)k++;else{x[k]=0;k--;}}return number; }int main(){cout<<"共有"<<Queue(Q_num)<<"个解"<<endl;return 0;}//递归方法实现哈密顿回路问题//指定一个城市为出发城市#include <string.h>#include <iostream>using namespace std;bool c[6][6];int x[6];int n=5;void output(int x[]){for(int i=1;i<=n;i++)c out<<x[i]<<' ';cout<<endl;return;}void hamilton(int k ){if(k>n && c[x[k-1]][1]==1)output(x);elsef or(int i=k;i<=n;i++){swap(x[k],x[i]);if ( c[x[k-1]][x[k]]==1)hamilton(k+1);swap(x[i],x[k]);}}int main(){int n = 5;memset(c, 0, sizeof(c));c[1][2] = true;c[2][1] = true;c[1][4] = true;c[4][1] = true;c[2][4] = true;c[4][2] = true;c[2][3] = true;c[3][2] = true;c[3][5] = true;c[5][3] = true;c[4][5] = true;c[5][4] = true;c[2][5] = true;c[5][2] = true;c[3][4] = true;c[4][3] = true;for(int i = 0; i <= n;i++){x[i] = i;}hamilton(2);//默认以第一个城市开始,搜索解空间树(子集树形式)直接从第二层开始//如果出发城市也可任选,则需要将c[0][i]=1,i=1~n,此时调用hamilton(1)即可cout << endl;return 0;}//哈密顿回路问题回溯法,解空间树按子集树构造,//采用迭代法实现//起始结点(出发城市)默认以第一个开始#include <string.h>#include <iostream>using namespace std;void hamilton(int n, int x[], boolc[6][6]){int i, k;bool*visited = new bool[n+1];for(i = 1; i <= n; i++){x[i] = 0;visited[i] = false;}visited[1]=1;x[1]=1;//默认以第一个城市开始k =2; //搜索解空间树(子集树形式)直接从第二层开始while(k >1){x[k]++;while(x[k] <= n)if(visited[x[k]]==0 &&c[x[k - 1]][x[k]]==1)break;elsex[k]++;if(x[k] <= n && k==n&& c[x[k]][1]==1){f or(k=1;k<=n;k++)cout<<x[k]<<' ';cout<<endl;k--;// break;输出一个解结束时用他替代上两句}else if(x[k]<=n &&k<n)//k!=n-1){v isited[x[k]]=1;k++;}else{x[k]=0;k--;visited[x[k]]=0;}}delete []visited; }int main(){int n = 5;bool c[6][6];memset(c, 0, sizeof(c));c[1][2] = true;c[2][1] = true;c[1][4] = true;c[4][1] = true;c[2][4] = true;c[4][2] = true;c[2][3] = true;c[3][2] = true;c[3][5] = true;c[5][3] = true;c[4][5] = true;c[5][4] = true;c[2][5] = true;c[5][2] = true;c[3][4] = true;c[4][3] = true;int x[6];hamilton(5, x, c);cout << endl;return 0;}。

算法设计与分析复习题目及答案

算法设计与分析复习题目及答案

分治法1、二分搜索算法是利用(分治策略)实现的算法。

9. 实现循环赛日程表利用的算法是(分治策略)27、Strassen矩阵乘法是利用(分治策略)实现的算法。

34.实现合并排序利用的算法是(分治策略)。

实现大整数的乘法是利用的算法(分治策略)。

17.实现棋盘覆盖算法利用的算法是(分治法)。

29、使用分治法求解不需要满足的条件是(子问题必须是一样的)。

不可以使用分治法求解的是(0/1背包问题)。

动态规划下列不是动态规划算法基本步骤的是(构造最优解)下列是动态规划算法基本要素的是(子问题重叠性质)。

下列算法中通常以自底向上的方式求解最优解的是(动态规划法)备忘录方法是那种算法的变形。

(动态规划法)最长公共子序列算法利用的算法是(动态规划法)。

矩阵连乘问题的算法可由(动态规划算法B)设计实现。

实现最大子段和利用的算法是(动态规划法)。

贪心算法能解决的问题:单源最短路径问题,最小花费生成树问题,背包问题,活动安排问题,不能解决的问题:N皇后问题,0/1背包问题是贪心算法的基本要素的是(贪心选择性质和最优子结构性质)。

回溯法回溯法解旅行售货员问题时的解空间树是(排列树)。

剪枝函数是回溯法中为避免无效搜索采取的策略回溯法的效率不依赖于下列哪些因素(确定解空间的时间)分支限界法最大效益优先是(分支界限法)的一搜索方式。

分支限界法解最大团问题时,活结点表的组织形式是(最大堆)。

分支限界法解旅行售货员问题时,活结点表的组织形式是(最小堆)优先队列式分支限界法选取扩展结点的原则是(结点的优先级)在对问题的解空间树进行搜索的方法中,一个活结点最多有一次机会成为活结点的是( 分支限界法).从活结点表中选择下一个扩展结点的不同方式将导致不同的分支限界法,以下除( 栈式分支限界法)之外都是最常见的方式.(1)队列式(FIFO)分支限界法:按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。

(2)优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。

回溯算法---例题7.图的m着色问题

回溯算法---例题7.图的m着色问题

回溯算法---例题7.图的m着⾊问题⼀.问题描述给定⽆向连通图G和m种不同的颜⾊.⽤这些颜⾊为图G的各项点着⾊,每个项点画⼀种颜⾊.是否有⼀种着⾊法,使G中每条边的2个顶点有着不同颜⾊?⼆.解题思路图的m⾊判定问题:给定⽆向连通图G和m种颜⾊。

⽤这些颜⾊为图G的各顶点着⾊. 问是否存在着⾊⽅法, 使得G中任2邻接点有不同颜⾊。

图的m⾊优化问题:给定⽆向连通图G,为图G的各顶点着⾊, 使图中任2邻接点着不同颜⾊,问最少需要⼏种颜⾊。

所需的最少颜⾊的数⽬m称为该图的⾊数若图G是可平⾯图,则它的⾊数不超过4⾊(4⾊定理).4⾊定理的应⽤:在⼀个平⾯或球⾯上的任何地图能够只⽤4种颜⾊来着⾊使得相邻的国家在地图上着有不同颜⾊例如:[这⾥有⼀个适⽤于任意图着⾊的Welch Powell法,感兴趣的同学可以看看.](#Welch Powell)回到该问题,我们可以很清晰地看出问题的解空间树是⼀棵排列树,因为我们确定n个元素满⾜某种性质的排列,这个性质就是⼀条边的两个点颜⾊不相同.⽽不是说找到n个元素的⼀个⼦集,这是要做的第⼀步.具体的算法实现上:设图G=(V, E), |V|=n, 颜⾊数= m, ⽤邻接矩阵a表⽰G, ⽤整数1, 2…m来表⽰m种不同的颜⾊。

顶点i所着的颜⾊⽤x[i]表⽰。

问题的解向量可以表⽰为n元组x={ x[1],...,x[n] }. x[i]Î{1,2,...,m},解空间树为排序树,是⼀棵n+1层的完全m叉树.在解空间树中做深度优先搜索, 约束条件: x[i] ≠ x[j], 如果a[j].[i] = 1.代码如下:// 图的m着⾊问题#include<bits/stdc++.h>using namespace std;class Color{friend int mColoring(int, int, int **);private:bool CanDraw(int k);void Backtrack(int i);int n, //图的顶点数m, //可⽤颜⾊数**a, //图的邻接矩阵*x; //当前解long sum; //当前已经找到的可m着⾊⽅案数};bool Color::CanDraw(int i) //检查第i层填写的颜⾊x[i]是否可⽤{for(int j=1; j<i; j++){if(a[i][j]==1 && x[j]==x[i])return false;}return true;}void Color::Backtrack(int i){if(i > n){sum++;cout<<"第"<<sum<<"个解:";for(int i=1; i<=n; i++)cout<<x[i]<<" ";cout<<endl;return;}for(int k=1; k<=m; k++) //依次从m种颜⾊中选择,由于每⼀个分⽀的处理⽅法⼀样,所以直接⽤⼀个循环,⽽不需要分别写{x[i] = k;if(CanDraw(i)){cout<<"颜⾊"<<k<<"可⾏,深⼊⼀层,将到达"<<i+1<<"层"<<endl;Backtrack(i+1);cout<<"回溯⼀层到达第"<<i<<"层"<<endl;}else{if(k==m) cout<<"当前层所有颜⾊选完,没有可⾏颜⾊,故将回溯⼀层到达第"<<i-1<<"层"<<endl;else cout<<"颜⾊"<<k<<"不可⾏,继续选择颜⾊"<<k+1<<endl;}x[i] = 0;}}int mColoring(int n, int m, int **a){Color X;// 初始化XX.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<<"请输⼊顶点个数和颜⾊种数:";int n, m;while(cin>>n>>m && n && m){cout<<"请输⼊邻接矩阵"<<endl;int **a = new int*[n+1];for(int i=0; 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<<"着⾊⽅案共有"<<ans<<"种"<<endl;for(int i=0; i<=n; i++) delete[] a[i];delete[] a;cout<<"请输⼊顶点个数和颜⾊种数:";}system("pause");return 0;}运⾏结果:由此可以结合排列树看⼀看,⼗分清晰明了.参考毕⽅明⽼师《算法设计与分析》课件.欢迎⼤家访问个⼈博客⽹站---,和我⼀起加油吧!针对任意图着⾊问题,Welch Powell⽅法:将G的结点按照度数递减的次序排列⽤第⼀种颜⾊对第⼀个结点着⾊,并按照结点排列的次序对与前⾯着⾊点不邻接的每⼀点着以相同颜⾊⽤第⼆种颜⾊对尚未着⾊的点重复步骤2,⽤第三种颜⾊继续这种作法,直到所有点着⾊完为⽌例如:。

图着色问题——精选推荐

图着色问题——精选推荐

图着⾊问题⼀、图着⾊问题(1)图的m可着⾊判定问题给定⽆向连通图G和m种不同的颜⾊。

⽤这些颜⾊为图G的各顶点着⾊,每个顶点着⼀种颜⾊。

是否有⼀种着⾊法使G中每条边的2个顶点着不同颜⾊。

(2)图的m可着⾊优化问题若⼀个图最少需要m种颜⾊才能使图中每条边连接的2个顶点着不同颜⾊,则称这个数m为该图的⾊数。

⼆、m可着⾊判定问题的解法【算法】(1)通过回溯的⽅法,不断的为每⼀个节点着⾊,在前⾯cur-1个节点都合法的着⾊之后,开始对第cur-1个节点进⾏着⾊,(2)这时候枚举可⽤的m个颜⾊,通过和第cur-1个节点相邻的节点的颜⾊,来判断这个颜⾊是否合法(3)如果找到那么⼀种颜⾊使得第cur-1个节点能够着⾊,那么说明m种颜⾊的⽅案在当前是可⾏的。

(4)cur每次迭代加1,如果cur增加到N并通过了检测,说明m种颜⾊是可满⾜的。

(5)注意,这⾥只是要求判断m种颜⾊是否可满⾜,所以找到任何⼀种⽅案就可以了。

【代码实现】#include<iostream>#include<cstring>using namespace std;const int maxn = 105;int G[maxn][maxn];int color[maxn];bool ans;int n,m,k;void init(){ans = 0;memset(G, 0 , sizeof G);memset(color, 0 , sizeof color);}void dfs(int cur){if(cur > n) {ans = 1;return;}for(int i=1; i<=m; i++){ //对cur结点尝试使⽤每⼀种颜⾊进⾏涂⾊bool flag = 1;//cur之前的结点必被涂⾊for(int j=1; j<cur; j++){if(G[j][cur] == 1 && color[j] == i){flag = 0;//只要有⼀个冲突都不⾏break;}}//如果可以涂上i颜⾊,则考虑下⼀个结点的情况if(flag){color[cur] = i;dfs(cur + 1);}//如果到这⼀步第cur个结点⽆法着⾊,则返回探寻其他⽅案else color[cur] = 0;//回溯 ;}}int main(){while(cin>>n>>k>>m){init();for(int i=1; i<=k; i++){int x,y;cin>>x>>y;G[x][y] = G[y][x] = 1;}dfs(1);cout<<ans<<endl;}return0;}三、m可着⾊拓展【问题】在上述基础上,求出m种颜⾊能够给图G涂⾊的总总⽅案数量【算法】由于这个时候要求总⽅案数量,所以在找到⼀种可⾏⽅案后,总是进⾏回溯再搜索其他的解决⽅案,与上⾯不同,上⾯是只需要找出⼀种⽅案即可,所以如果找到了就不需要再回溯了,所以在这⾥只需要把回溯语句的位置写到dfs语句的后⾯即可。

m着色问题

m着色问题

{ private:
int n,
//图的顶点个数
m,
//可用颜色数
**a,
//图的邻接矩阵,用来表示一个无向连通图G
*x;
//当前解
long sum;
//当前已找到的可m着色方案数
public:
color();
int ok(int k);
void backtrack(int t);
void op();
~color();
};
/*构造函数的定义*/
color::color()
{ int k;
//边数
int i,j;
int v1,v2;
//构成边的两顶点
ifstream fin("input.txt",ios::nocreate);
if(!fin)
{cerr<<"文件不存在";
exit(0); }
fin>>n>>k>>m;
a[v1][v2]或a[v2][v1]赋值
}
if(!(x=new int[n+1]))
{cerr<<"insufficient memory!"<<endl;
exit(0); }
for(i=0;i<=n;i++)
x[i]=0;
//对x数组初始化,作为未着色情况
sum=0;
fin.close();
}
if(ok(t))
backtrack(t+1); //如果该颜色可用,判断下一个顶点
}
}
/*输出函数的定义*/
void color::op()

回溯法解决图着色问题

回溯法解决图着色问题

回溯法解决图着色问题回溯法解决图着色问题2010-05-20 20:151回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。

回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

用回溯算法解决问题的一般步骤为:一、定义一个解空间,它包含问题的解。

二、利用适于搜索的方法组织解空间。

三、利用深度优先法搜索解空间。

四、利用限界函数避免移动到不可能产生解的子空间。

问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。

回溯法是一个既带有系统性又带有跳跃性的的搜索算法。

它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。

算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。

如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。

否则,进入该子树,继续按深度优先的策略进行搜索。

回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。

而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。

这种以深度优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题.递归回溯:由于回溯法是对解空间的深度优先搜索,因此在一般情况下可用递归函数来实现回溯法如下:procedure try(i:integer);var begin if in then输出结果else for j:=下界to上界do begin x:=h[j];if可行{满足限界函数和约束条件}then begin置值;try(i+1);end;end;end;说明:i是递归深度;n是深度控制,即解空间树的的高度;可行性判断有两方面的内容:不满约束条件则剪去相应子树;若限界函数越界,也剪去相应子树;两者均满足则进入下一层;搜索:全面访问所有可能的情况,分为两种:不考虑给定问题的特有性质,按事先顶好的顺序,依次运用规则,即盲目搜索的方法;另一种则考虑问题给定的特有性质,选用合适的规则,提高搜索的效率,即启发式的搜索。

着色问题与排队论

着色问题与排队论
void GraphColor(int n, int c[ ][ ], int m) //所有数组下标从 1 开始 { for (i=1; i<=n; i++ ) //将数组 color[n]初始化为 0 color[i]=0; k=1; while (k>=1) { color[k]=color[k]+1; while (color[k]<=m) if Ok(k) break; else color[k]=color[k]+1; //搜索下一个颜色
12.1.1
顶点着色问题
一、基本定义 对图 G=(V,E),设 S 是 V 的一个子集,若 S 中任意两个顶点在 G 中均不相邻,则称 S 为 G 的一个独立集,如果 G 不包含适合|S'|>|S|的独立集 S',则称 S 为 G 的最大独立集。 设 K 是 G 的一个独立集,并且对于 V\K 的任一顶点 v,K+v 都不是 G 的独立集,则 称 K 是 G 的一个极大覆盖。极大独立集的补集称为极小覆盖, V 的子集 K 是 G 的极小覆 盖当且仅当:对于每个顶点 v 或者 r 属于 K,或者 v 的所有邻点属于 K(但两者不同时成 立) 。 G 的一个 k 顶点着色是指 k 种颜色 1,2,…,k 对于 G 各顶点的一个分配,如果任意两个 相邻顶点都分配到不同的颜色,则称着色是正常的。换句话说,无环图 G 的一个正常 k 顶 点着色是把 V 分成 k 个(可能有空的)独立集的一个分类 (V1,V2,„,Vk)。当 G 有一个正常 k 顶点着色时,就成 G 是 k 顶点可着色的。 G 的色数 X(G)是指 G 为 k 可着色的 k 的最小值,若 X(G)=k,则称 G 是 k 色的。 ·160·

算法设计与分析考试题目及答案

算法设计与分析考试题目及答案

算法设计与分析考试题目及答案Revised at 16:25 am on June 10, 2021I hope tomorrow will definitely be better算法分析与设计期末复习题一、 选择题1.应用Johnson 法则的流水作业调度采用的算法是DA. 贪心算法B. 分支限界法C.分治法D. 动态规划算法塔问题如下图所示;现要求将塔座A 上的的所有圆盘移到塔座B 上,并仍按同样顺序叠置;移动圆盘时遵守Hanoi 塔问题的移动规则;由此设计出解Hanoi 塔问题的递归算法正确的为:B3. 动态规划算法的基本要素为C A. 最优子结构性质与贪心选择性质 B .重叠子问题性质与贪心选择性质 C .最优子结构性质与重叠子问题性质 D. 预排序与递归调用4. 算法分析中,记号O 表示B , 记号Ω表示A , 记号Θ表示D ; A.渐进下界 B.渐进上界 C.非紧上界 D.紧渐进界 E.非紧下界5. 以下关于渐进记号的性质是正确的有:A A.f (n)(g(n)),g(n)(h(n))f (n)(h(n))=Θ=Θ⇒=Θ B. f (n)O(g(n)),g(n)O(h(n))h(n)O(f (n))==⇒= C. Ofn+Ogn = Omin{fn,gn} D. f (n)O(g(n))g(n)O(f (n))=⇔=Hanoi 塔A. void hanoiint n, int A, int C, int B { if n > 0 {hanoin-1,A,C, B; moven,a,b;hanoin-1, C, B, A; } B. void hanoiint n, int A, int B, int C { if n > 0 {hanoin-1, A, C, B; moven,a,b; hanoin-1, C, B, A; }C. void hanoiint n, int C, int B, int A { if n > 0 { hanoin-1, A, C, B; moven,a,b; hanoin-1, C, B, A; }D. void hanoiint n, int C, int A, int B { if n > 0 {hanoin-1, A, C, B; moven,a,b;hanoin-1, C, B, A; }6.能采用贪心算法求最优解的问题,一般具有的重要性质为:AA. 最优子结构性质与贪心选择性质B.重叠子问题性质与贪心选择性质C.最优子结构性质与重叠子问题性质D. 预排序与递归调用7. 回溯法在问题的解空间树中,按D策略,从根结点出发搜索解空间树;广度优先 B. 活结点优先 C.扩展结点优先 D. 深度优先8. 分支限界法在问题的解空间树中,按A策略,从根结点出发搜索解空间树;A.广度优先 B. 活结点优先 C.扩展结点优先 D. 深度优先9. 程序块A是回溯法中遍历排列树的算法框架程序;A.B.C.D.10.xk的个数;11. 常见的两种分支限界法为DA. 广度优先分支限界法与深度优先分支限界法;B. 队列式FIFO分支限界法与堆栈式分支限界法;C. 排列树法与子集树法;D. 队列式FIFO分支限界法与优先队列式分支限界法;12. k带图灵机的空间复杂性Sn是指BA.k带图灵机处理所有长度为n的输入时,在某条带上所使用过的最大方格数;B.k带图灵机处理所有长度为n的输入时,在k条带上所使用过的方格数的总和;C.k带图灵机处理所有长度为n的输入时,在k条带上所使用过的平均方格数;D.k带图灵机处理所有长度为n的输入时,在某条带上所使用过的最小方格数;13. N P类语言在图灵机下的定义为DA.NP={L|L是一个能在非多项式时间内被一台NDTM所接受的语言};B.NP={L|L是一个能在多项式时间内被一台NDTM所接受的语言};C.NP={L|L是一个能在多项式时间内被一台DTM所接受的语言};D.NP={L|L是一个能在多项式时间内被一台NDTM所接受的语言};14. 记号O的定义正确的是A;A.Ogn = { fn | 存在正常数c和n0使得对所有n≥n0有:0≤ fn ≤cgn };B.Ogn = { fn | 存在正常数c和n0使得对所有n≥n0有:0≤ cgn ≤fn };>0使得对所有n≥n0C.Ogn = { fn | 对于任何正常数c>0,存在正数和n有:0 ≤fn<cgn };>0使得对所有n≥n0D.Ogn = { fn | 对于任何正常数c>0,存在正数和n有:0 ≤cgn < fn };15. 记号Ω的定义正确的是B;A.Ogn = { fn | 存在正常数c和n0使得对所有n≥n0有:0≤ fn ≤cgn };B.Ogn = { fn | 存在正常数c和n0使得对所有n≥n0有:0≤ cgn ≤fn };>0使得对所有n≥n0有:C.gn = { fn | 对于任何正常数c>0,存在正数和n0 ≤fn<cgn };D.gn = { fn | 对于任何正常数c>0,存在正数和n0 >0使得对所有n≥n0有:0 ≤cgn < fn };二、 填空题1. 下面程序段的所需要的计算时间为 2O(n ) ;2.3.4. 5.6. 用回溯法解题的一个显着特征是在搜索过程中动态产生问题的解空间;在任何时刻,算法只保存从根结点到当前扩展结点的路径;如果解空间树 中从根结点到叶结点的最长路径的长度为hn,则回溯法所需的计算空间通常为Ohn ;7. 回溯法的算法框架按照问题的解空间一般分为子集树算法框架与排列树算法框架;8. 用回溯法解0/1背包问题时,该问题的解空间结构为子集树结构; 9.用回溯法解批处理作业调度问题时,该问题的解空间结构为排列树结构; 10.用回溯法解0/1背包问题时,计算结点的上界的函数如下所示,请在空格中填入合适的内容:11. n m12. 用回溯法解图的m着色问题时,使用下面的函数OK检查当前扩展结点的每一个儿子所相应的颜色的可用性,则需耗时渐进时间上限Omn;13.;设分分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需用fn个单位时间;用Tn表示该分治法解规模为|P|=n的问题所需的计算时间,则有:(1)1 ()(/)()1O nT nkT n m f n n=⎧=⎨+>⎩通过迭代法求得Tn的显式表达式为:log1log()(/)nmk j jmjT n n k f n m-==+∑试证明Tn的显式表达式的正确性;2. 举反例证明0/1背包问题若使用的算法是按照p i/w i的非递减次序考虑选择的物品,即只要正在被考虑的物品装得进就装入背包,则此方法不一定能得到最优解此题说明0/1背包问题与背包问题的不同;证明:举例如:p={7,4,4},w={3,2,2},c=4时,由于7/3最大,若按题目要求的方法,只能取第一个,收益是7;而此实例的最大的收益应该是8,取第2,3 个;3. 求证:Ofn+Ogn = Omax{fn,gn} ;证明:对于任意f1n∈ Ofn ,存在正常数c1和自然数n1,使得对所有n≥n1,有f1n≤ c1fn ;类似地,对于任意g1n ∈ Ogn ,存在正常数c2和自然数n2,使得对所有n≥n2,有g1n ≤c2gn ;令c3=max{c1, c2}, n3 =max{n1, n2},hn= max{fn,gn} ;则对所有的 n ≥ n3,有f1n +g1n ≤ c1fn + c2gn≤c3fn + c3gn= c3fn + gn≤ c32 max{fn,gn} = 2c3hn = Omax{fn,gn} .4. 求证最优装载问题具有贪心选择性质;最优装载问题:有一批集装箱要装上一艘载重量为c 的轮船;其中集装箱i 的重量为Wi;最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船; 设集装箱已依其重量从小到大排序,x 1,x 2,…,x n 是最优装载问题的一个最优解;又设1min{|1}i i nk i x ≤≤== ;如果给定的最优装载问题有解,则有1k n ≤≤;证明: 四、 解答题1. 机器调度问题;问题描述:现在有n 件任务和无限多台的机器,任务可以在机器上得到处理;每件任务的开始时间为s i ,完成时间为f i ,s i <f i ;s i ,f i 为处理任务i 的时间范围;两个任务i,j 重叠指两个任务的时间范围区间有重叠,而并非指i,j 的起点或终点重合;例如:区间1,4与区间2,4重叠,而与4,7不重叠;一个可行的任务分配是指在分配中没有两件重叠的任务分配给同一台机器;因此,在可行的分配中每台机器在任何时刻最多只处理一个任务;最优分配是指使用的机器最少的可行分配方案;问题实例:若任务占用的时间范围是{1,4,2,5,4,5,2,6,4,7},则按时完成所有任务最少需要几台机器提示:使用贪心算法画出工作在对应的机器上的分配情况;2. 已知非齐次递归方程:f (n)bf (n 1)g(n)f (0)c =-+⎧⎨=⎩ ,其中,b 、c 是常数,gn 是n 的某一个函数;则fn 的非递归表达式为:nnn i i 1f (n)cb b g(i)-==+∑;现有Hanoi 塔问题的递归方程为:h(n)2h(n 1)1h(1)1=-+⎧⎨=⎩ ,求hn 的非递归表达式;解:利用给出的关系式,此时有:b=2, c=1, gn=1, 从n 递推到1,有: 3. 单源最短路径的求解;问题的描述:给定带权有向图如下图所示G =V,E,其中每条边的权是非负实数;另外,还给定V 中的一个顶点,称为源;现在要计算从源到所有其它各顶点的最短路长度;这里路的长度是指路上各边权之和;这个问题通常称为单源最短路径问题;解法:现采用Dijkstra 算法计算从源顶点1到其它顶点间最短路径;请将此过程填入下表中;4. 请写出用回溯法解装载问题的函数; 装载问题:有一批共n 个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i 的重量为wi,且121ni i w c c =≤+∑;装载问题要求确定是否有一个合理的装载方案可将这n 个集装箱装上这2艘轮船;如果有,找出一种装载方案;解:void backtrack int i{用分支限界法解装载问题时,对算法进行了一些改进,下面的程序段给出了改进部分;试说明斜线部分完成什么功能,以及这样做的原因,即采用这样的方式,算法在执行上有什么不同;初始时将;也就是说,重量仅在搜索进入左子树是增加,因此,可以在算法每一次进入左子树时更新bestw 的值;43 2 110030maxint10 - {1} 初始 dist5 dist4 dist3 dist2 u S 迭代7. 最长公共子序列问题:给定2个序列X={x 1,x2,…,xm }和Y={y 1,y2,…,yn },找出X 和Y 的最长公共子序列;由最长公共子序列问题的最优子结构性质建立子问题最优值的递归关系;用cij 记录序列Xi 和Yj 的最长公共子序列的长度;其中, Xi={x1,x2,…,xi};Y j={y1,y2,…,yj};当i=0或j=0时,空序列是Xi 和Yj 的最长公共子序列;故此时Cij=0;其它情况下,由最优子结构性质可建立递归关系如下:00,0[][][1][1]1,0;max{[][1],[1][]},0;i j i ji j c i j c i j i j x y c i j c i j i j x y ⎧==⎪=--+>=⎨⎪-->≠⎩在程序中,bij 记录Cij 的值是由哪一个子问题的解得到的;8.1.2.3.4.5.用回溯法解问题时,应明确定义问题的解空间,问题的解空间至少应包含___________;6.动态规划算法的基本思想是将待求解问题分解成若干____________,先求解___________,然后从这些____________的解得到原问题的解;7.以深度优先方式系统搜索问题解的算法称为_____________;背包问题的回溯算法所需的计算时间为_____________,用动态规划算法所需的计算时间为____________;9.动态规划算法的两个基本要素是___________和___________;10.二分搜索算法是利用_______________实现的算法;二、综合题50分1.写出设计动态规划算法的主要步骤;2.流水作业调度问题的johnson算法的思想;3.若n=4,在机器M1和M2上加工作业i所需的时间分别为ai 和bi,且a 1,a2,a3,a4=4,5,12,10,b1,b2,b3,b4=8,2,15,9求4个作业的最优调度方案,并计算最优值;4.使用回溯法解0/1背包问题:n=3,C=9,V={6,10,3},W={3,4,4},其解空间有长度为3的0-1向量组成,要求用一棵完全二叉树表示其解空间从根出发,左1右0,并画出其解空间树,计算其最优值及最优解;5.设S={X1,X2,···,Xn}是严格递增的有序集,利用二叉树的结点来存储S中的元素,在表示S的二叉搜索树中搜索一个元素X,返回的结果有两种情形,1在二叉搜索树的内结点中找到X=Xi ,其概率为bi;2在二叉搜索树的叶结点中确定X∈Xi ,Xi+1,其概率为ai;在表示S的二叉搜索树T中,设存储元素Xi的结点深度为C i ;叶结点Xi,Xi+1的结点深度为di,则二叉搜索树T的平均路长p为多少假设二叉搜索树Tij={Xi ,Xi+1,···,Xj}最优值为mij,Wij= ai-1+bi+···+bj+aj,则mij1<=i<=j<=n递归关系表达式为什么6.描述0-1背包问题;三、简答题30分1.流水作业调度中,已知有n个作业,机器M1和M2上加工作业i所需的时间分别为ai 和bi,请写出流水作业调度问题的johnson法则中对ai和bi的排序算法;函数名可写为sorts,n2.最优二叉搜索树问题的动态规划算法设函数名binarysearchtree答案:一、填空1.确定性有穷性可行性 0个或多个输入一个或多个输出2.时间复杂性空间复杂性时间复杂度高低3. 该问题具有最优子结构性质4.{BABCD}或{CABCD}或{CADCD}5.一个最优解6.子问题子问题子问题7.回溯法8. on2n omin{nc,2n}9.最优子结构重叠子问题10.动态规划法二、综合题1.①问题具有最优子结构性质;②构造最优值的递归关系表达式;③最优值的算法描述;④构造最优解;2. ①令N1={i|ai<bi},N2={i|ai>=bi};②将N1中作业按ai的非减序排序得到N1’,将N2中作业按bi的非增序排序得到N2’;③N1’中作业接N2’中作业就构成了满足Johnson法则的最优调度;3.步骤为:N1={1,3},N2={2,4};N 1’={1,3}, N2’={4,2};最优值为:384.解空间为{0,0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,0,1, 1,1,0,1,1,1}; 解空间树为:该问题的最优值为:16 最优解为:1,1,0 5.二叉树T 的平均路长P=∑=+ni 1Ci)(1*bi +∑=nj 0dj *aj{mij=0 i>j6.已知一个背包的容量为C,有n 件物品,物品i 的重量为W i ,价值为V i ,求应如何选择装入背包中的物品,使得装入背包中物品的总价值最大; 三、简答题 1.void sortflowjope s,int n {int i,k,j,l;fori=1;i<=n-1;i++ag=0 k++; ifk>n break;ag==0ifsk.a>sj.a k=j; swapsi.index,sk.index; swapsi.tag,sk.tag;} }l=i;<sj.b k=j;swapsi.index,sk.index; ag,sk.tag; }mij=Wij+min{mik+mk+1j} 1<=i<=j<=n,mii-1=0}2.void binarysearchtreeint a,int b,int n,int m,int s,int w{int i,j,k,t,l;fori=1;i<=n+1;i++{wii-1=ai-1;mii-1=0;}forl=0;l<=n-1;l++Init-single-sourceG,s2. S=Φ3. Q=VGQ<> Φdo u=minQS=S∪{u}for each vertex 3do 4四、算法理解题本题10分根据优先队列式分支限界法,求下图中从v1点到v9点的单源最短路径,请画出求得最优解的解空间树;要求中间被舍弃的结点用×标记,获得中间解的结点用单圆圈○框起,最优解用双圆圈◎框起;五、算法理解题本题5分设有n=2k个运动员要进行循环赛,现设计一个满足以下要求的比赛日程表:①每个选手必须与其他n-1名选手比赛各一次;②每个选手一天至多只能赛一次;③循环赛要在最短时间内完成;1如果n=2k,循环赛最少需要进行几天;2当n=23=8时,请画出循环赛日程表;六、算法设计题本题15分分别用贪心算法、动态规划法、回溯法设计0-1背包问题;要求:说明所使用的算法策略;写出算法实现的主要步骤;分析算法的时间;七、算法设计题本题10分通过键盘输入一个高精度的正整数nn的有效位数≤240,去掉其中任意s个数字后,剩下的数字按原左右次序将组成一个新的正整数;编程对给定的n 和s,寻找一种方案,使得剩下的数字组成的新数最小;样例输入178543S=4样例输出13一、填空题本题15分,每小题1分1.规则一系列运算2. 随机存取机RAMRandom Access Machine;随机存取存储程序机RASPRandom Access Stored Program Machine;图灵机Turing Machine3. 算法效率4. 时间、空间、时间复杂度、空间复杂度5.2n6.最好局部最优选择7. 贪心选择最优子结构二、简答题本题25分,每小题5分1、分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同;对这k个子问题分别求解;如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止;将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解;2、“最优化原理”用数学化的语言来描述:假设为了解决某一优化问题,需要依次作出n个决策D1,D2,…,Dn,如若这个决策序列是最优的,对于任何一个整数k,1 < k < n,不论前面k个决策是怎样的,以后的最优决策只取决于由前面决策所确定的当前状态,即以后的决策Dk+1,Dk+2,…,Dn也是最优的;3、某个问题的最优解包含着其子问题的最优解;这种性质称为最优子结构性质;4、回溯法的基本思想是在一棵含有问题全部可能解的状态空间树上进行深度优先搜索,解为叶子结点;搜索过程中,每到达一个结点时,则判断该结点为根的子树是否含有问题的解,如果可以确定该子树中不含有问题的解,则放弃对该子树的搜索,退回到上层父结点,继续下一步深度优先搜索过程;在回溯法中,并不是先构造出整棵状态空间树,再进行搜索,而是在搜索过程,逐步构造出状态空间树,即边搜索,边构造;5、PPolynomial问题:也即是多项式复杂程度的问题;NP就是Non-deterministicPolynomial的问题,也即是多项式复杂程度的非确定性问题;NPCNP Complete问题,这种问题只有把解域里面的所有可能都穷举了之后才能得出答案,这样的问题是NP里面最难的问题,这种问题就是NPC问题;三、算法填空本题20分,每小题5分1、n后问题回溯算法1 Mj&&Li+j&&Ri-j+N2 Mj=Li+j=Ri-j+N=1;3 tryi+1,M,L,R,A4 Aij=05 Mj=Li+j=Ri-j+N=0 2、数塔问题; 1c<=r2trc+=tr+1c 3trc+=tr+1c+1 3、Hanoi 算法 1movea,c2Hanoin-1, a, c , b 3Movea,c 4、1pv=NIL 2pv=u3 v ∈adju 4Relaxu,v,w四、算法理解题本题10分五、18天2分;2当n=23=8时,循环赛日程表3分;六、算法设计题本题15分 1贪心算法 Onlogn ➢ 首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包;若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包;依此策略一直地进行下去,直到背包装满为止; ➢ 具体算法可描述如下:void Knapsackint n,float M,float v,float w,float x {Sortn,v,w; int i;for i=1;i<=n;i++ xi=0; float c=M;for i=1;i<=n;i++ {if wi>c break; xi=1; c-=wi; }if i<=n xi=c/wi; }2动态规划法 Oncmi,j 是背包容量为j,可选择物品为i,i+1,…,n 时0-1背包问题的最优值;由0-1背包问题的最优子结构性质,可以建立计算mi,j 的递归式如下;void KnapSackint v,int w,int c,int n,int m11 {int jMax=minwn-1,c;for j=0;j<=jMax;j++ /mn,j=0 0=<j<wn/ mnj=0;1 2 3 4 5 6 7 82 1 43 6 5 8 73 4 1 2 7 8 5 64 3 2 1 8 7 6 55 6 7 8 1 2 3 4 6 5 8 7 2 1 4 37 8 5 6 3 4 1 28 7 6 5 4 3 2 1for j=wn;j<=c;j++ /mn,j=vn j>=wn/mnj=vn;for i=n-1;i>1;i--{ int jMax=minwi-1,c;for j=0;j<=jMax;j++ /mi,j=mi+1,j 0=<j<wi/mij=mi+1j;for j=wi;j<=c;j++/mn,j=vn j>=wn/mij=maxmi+1j,mi+1j-wi+vi;}m1c=m2c;ifc>=w1m1c=maxm1c,m2c-w1+v1;}3回溯法 O2ncw:当前重量 cp:当前价值 bestp:当前最优值voidbacktrack int i//回溯法 i初值1{ifi>n //到达叶结点{ bestp=cp; return; }ifcw+wi<=c //搜索左子树{cw+=wi;cp+=pi;backtracki+1;cw-=wi;cp-=pi;}ifBoundi+1>bestp//搜索右子树backtracki+1;}七、算法设计题本题10分为了尽可能地逼近目标,我们选取的贪心策略为:每一步总是选择一个使剩下的数最小的数字删去,即按高位到低位的顺序搜索,若各位数字递增,则删除最后一个数字,否则删除第一个递减区间的首字符;然后回到串首,按上述规则再删除下一个数字;重复以上过程s次,剩下的数字串便是问题的解了;具体算法如下:输入s, n;while s > 0{ i=1; //从串首开始找while i < lengthn && ni<ni+1{i++;}deleten,i,1; //删除字符串n的第i个字符s--;}while lengthn>1&& n1=‘0’deleten,1,1; //删去串首可能产生的无用零输出n;。

用回溯法求解图的m着色问题

用回溯法求解图的m着色问题

实验二用回溯法求解图的m着色问题一、实验目的12、使用回溯法编程求解图的m着色问题。

二、实验原理回溯法是一个既带有系统性又带有跳跃性的的搜索算法。

回溯法在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。

算法搜索至解空间树的任何一个结点时,总是先判断该结点是否肯定不包含问题的解,如果肯定不包含,则跳过对以该结点为根的子树搜索。

否则,进入该子树,继续按深度优先的策略进行搜索。

回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。

而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可结束。

回溯法从开始结点(根结点)出发,以深度优先搜索的方式搜索整个解空间。

这个开始结点就成为一个活结点,同时也成为当前的扩展结点。

在当前的扩展结点处,搜索向纵深方向移至一个新结点。

这个新结点就成为一个新的活结点,并成为当前扩展结点。

如果在当前的扩展结点处不能再向纵深方向移动,则当前的扩展结点就成为死结点。

此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。

回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已无活结点时为止。

三、问题描述给定一个无向连通图G和m种不同的颜色。

用这些颜色为图G的各顶点着色,每个顶点着一种颜色。

若一个图最少需要m种颜色才能使图中任何一条边连接的2个顶点着有不同的颜色,则称这个数m为该图的色数。

求一个图的色数m的问题称为图的m可着色优化问题。

设计一个算法,找出用m种颜色对一个图进行着色的不同方案。

四、算法设计与分析用邻接矩阵a来表示一个无向连通图G=(V,E)。

用整数1,2,…,m来表示m 种不同的颜色。

x[i]表示顶点i所着的颜色来,则问题的解向量可以表示为n元组x[1:n]。

问题的解空间可表示一棵高度为n+1的完全m叉树。

解空间树的第i层中每一结点都有m个儿子,每个儿子相应于x[i]的m个可能的着色之一,第n+1层结点均为叶结点。

算法设计与分析5.8图的m着色问题

算法设计与分析5.8图的m着色问题

算法设计与分析5.8图的m着色问题/************************************************************* * 5.8 图的 m 着色问题** 给定无向连通图 G 和 m 种不同的颜色。

用这些颜色为图 G 和各顶点着色,每* 个顶点着一种颜色。

是否有一种着色法使得图 G 中每条边的两个顶点着不同的颜* 色。

这个问题是图的 m 可着色判定问题。

若一个图最少需要 m 种颜色才能使图* 中的每条边连接的两个顶点着不同的颜色,则称这个数 m 为该图的色数。

求一个* 图的色数 m 的问题称为图的 m 可着色优化问题。

** 子集树,O(n*(m^n))时间复杂度************************************************************/ import java.util.Arrays;public class Coloring {static int n; //图的顶点数static int m; //可用颜色数static boolean[][] a; //图的邻接矩阵static int[] x; //当前解static long sum; //当前找到的可 m 着色的方案数/**** @param matrix 地图* @param mm 颜色数* @return 着色方案数*/public static long mColoring(boolean[][] matrix, int mm) { a = matrix;n = a.length;m = mm;x = new int[n];sum = 0;trackback(0);return sum;}private static void trackback(int t) {if (t == n) {sum++;System.out.println(Arrays.toString(x));} else {for (int i = 0; i < m; i++) {x[t] = i;if (valid(t)) {trackback(t + 1);}}}}private static boolean valid(int t) {//检查颜色可用性for (int i = 0; i < n; i++) {if (a[t][i] && x[i] == x[t]) {return false; }}return true; }}。

图的着色问题

图的着色问题

顶点着色-基本概念
• K可着色:G的一个k顶点着色是指k种颜色1,2,…,k对于G各顶点的 可着色: 的一个k顶点着色是指k种颜色1,2,…,k对于G 1,2, 对于 一个分配,如果任意两个相邻顶点都分配到不同的颜色, 一个分配,如果任意两个相邻顶点都分配到不同的颜色,则称着 色是正常的。换句话说,无环图G的一个正常k顶点着色是把V 色是正常的。换句话说,无环图G的一个正常k顶点着色是把V分成 可能有空的)独立集的一个分类( 2,… k个(可能有空的)独立集的一个分类(V1,V2,…,Vk)。当G有一个 正常k顶点着色时,就成G 顶点可着色的。 正常k顶点着色时,就成G是k顶点可着色的。 • G的色数X(G)是指G为k可着色的k的最小值,若X(G)=k,则称G 的色数X 是指G 可着色的k的最小值, =k,则称G 色的。 是k色的。 • 事实上,如果我们将同色的顶点列入一个顶点子集,那么求X(G) 事实上,如果我们将同色的顶点列入一个顶点子集,那么求X 就转为求满足下列条件的最少子集数k 就转为求满足下列条件的最少子集数k: 两两子集中的顶点不同; (1)两两子集中的顶点不同; 子集中的两两顶点不相邻。 (2)子集中的两两顶点不相邻。 显然有: 为平凡图, =1; 显然有: (i)若G为平凡图,则X(G)=1; ii) 为偶图, (ii)若G为偶图,则X(G)=2 iii)对任意图G Δ+1(这里Δ (iii)对任意图G,有X(G)≤Δ+1(这里Δ表示为顶点 数最大值) 数最大值)
问题来源
图的着色
• 通常所说的着色问题是指下述两类问题: 通常所说的着色问题是指下述两类问题: • 1.给定无环图G=(V,E),用m种颜色为图中 的每条边着色,要求每条边着一种颜色, 的每条边着色,要求每条边着一种颜色,并 使相邻两条边有着不同的颜色, 使相邻两条边有着不同的颜色,这个问题称 为图的边着色问题。 为图的边着色问题。 • 2.给定无向图G=(V,E),用m种颜色为图中 的每个顶点着色,要求每个顶点着一种颜色, 的每个顶点着色,要求每个顶点着一种颜色, 并使相邻两顶点之间有着不同的颜色, 并使相邻两顶点之间有着不同的颜色,这个 问题称为图的顶着色问题。 问题称为图的顶着色问题。

图着色问题 ppt课件

图着色问题 ppt课件

例子 :
图着色问题
邻接矩阵:B
1
0
1
1
1
C 1 1 0 0 1
D
0
1
0
0
1
E 0 1 1 1 0
色,要求每个顶点着一种颜色,并使相邻两顶点之间有着不同 的颜色,这个问题称为图的顶点着色问题。
边着色:给定无环图G=(V,E),用m种颜色为图中的每条边着色,
要求每条边着一种颜色,并使相邻两条边有着不同的颜色,这 个问题称为图的边着色问题。
图着色问题
顶点着色问题的基本概念
m可着色:若一个图最少需要m种颜色才能使图中每条边连接的两个顶 点着不同的颜色,则称m为该图的色数。
图的着色问题
主讲人:XXX
图着色问题
内容
问题来源 基本概念 常用算法 回溯法 程序演示
图着色问题
问题来源——四色问题
• 图的着色问题是由地图的着色问题引申而来的:用m种颜色为地 图着色,使得地图上的每一个区域着一种颜色,且相邻区域颜 色不同。
• 四色问题:“任何一张地图只用四种颜色就能使具有共同边界 的国家着上不同的颜色。”
求m的问题称为图的m可着色优化问题。
独立集:对图G=(V,E),设S是V的一个子集,其中任意两个顶点在G中 均不相邻,则称S为G的一个独立集。 最大独立集:如果G不包含适合|S'|>|S|的独立集S',则称S为G的最
大独立集。
极大覆盖:设K是G的一个独立集,并且对于V-K的任一顶点v,K+v都 不是G的独立集,则称K是G的一个极大覆盖。 极小覆盖:极大独立集的补集称为极小覆盖。
图着色问题
问题处理:如果把每一个区域收缩为一个顶点,把相邻两个区域用一 条边相连接,就可以把一个区域图抽象为一个平面图。 例:图(a)所示的区域图可抽象为图(b)所表示的平面图。区域用 城市名表示,颜色用数字表示,则图中表示了不同区域的不同着色问 题。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验二用回溯法求解图的m着色问题
一、实验目的
1、掌握回溯法求解问题的一般特征和步骤
2、使用回溯法编程求解图的m着色问题。

二、实验原理
回溯法是一个既带有系统性又带有跳跃性的的搜索算法。

回溯法在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。

算法搜索至解空间树的任何一个结点时,总是先判断该结点是否肯定不包含问题的解,如果肯定不包含,则跳过对以该结点为根的子树搜索。

否则,进入该子树,继续按深度优先的策略进行搜索。

回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。

而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可结束。

回溯法从开始结点(根结点)出发,以深度优先搜索的方式搜索整个解空间。

这个开始结点就成为一个活结点,同时也成为当前的扩展结点。

在当前的扩展结点处,搜索向纵深方向移至一个新结点。

这个新结点就成为一个新的活结点,并成为当前扩展结点。

如果在当前的扩展结点处不能再向纵深方向移动,则当前的扩展结点就成为死结点。

此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。

回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已无活结点时为止。

三、问题描述
给定一个无向连通图G和m种不同的颜色。

用这些颜色为图G的各顶点着色,每个顶点着一种颜色。

若一个图最少需要m种颜色才能使图中任何一条边连接的2个顶点着有不同的颜色,则称这个数m为该图的色数。

求一个图的色数m的问题称为图的m可着色优化问题。

设计一个算法,找出用m种颜色对一个图进行着色的不同方案。

四、算法设计与分析
用邻接矩阵a来表示一个无向连通图G=(V,E)。

用整数1,2,…,m来表示m种不同的颜色。

x[i]表示顶点i所着的颜色来,则问题的解向量可以表示为n元组x[1:n]。

问题的解空间可表示一棵高度为n+1的完全m叉树。

解空间树的第i层中每一结点都有m个儿子,每个儿子相应于x[i]的m个可能的着色之一,第n+1层结点均为叶结点。

在回溯算法Backtrack中,当i>n时,表示算法已搜索至一个叶结点,得到一个新的m着色方案,因此当前已找到的可m着色方案数sum增1。

当i≤n时,当前扩展结点Z是解空间树中的一个内部结点。

该结点有x[i]=1,2,…,m。

对当前扩展结点Z的每一个儿子结点,由函数Ok检查其可行性,并以深度优先的方式递归地对可行子树进行搜索,或剪去不可行子树。

五、实验结果
源程序:
#include<iostream>
using namespace std;
int color[100],sum;
bool ok(int k,int c[100][100])
{
for(int i=1;i<k;i++)
if(c[k][i]==1&&color[i]==color[k])
return false;
return true;
}
void backtrack(int k,int n,int m,int c[100][100]) {
if(k>n){
for(int i=1;i<=n;i++)
cout<<color[i]<<" ";
cout<<endl;
sum++;
}
else
for(int i=1;i<=m;i++){
color[k]=i;
if(ok(k,c)) backtrack(k+1,n,m,c);
color[k]=0;
}
}
int main()
{
int i,j,n,m;
int c[100][100];
cout<<"输入顶点数n和着色数m:\n";
cin>>n;
cin>>m;
cout<<"输入无向图的邻接矩阵:\n";
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>c[i][j];
cout<<"着色所有可能的解:\n";
backtrack(1,n,m,c);
cout<<"着色可能解的总数为:"<<sum<<endl;
system("pause");
return 0;
}。

相关文档
最新文档