回溯法-关于图的m着色问题的疑问

问题描述

关于图的m着色问题的疑问

回溯算法的Backtrack()函数里最后为什么要有x[i]=0,不然结果不是显示的所有着色方案。
#include "stdio.h"
#include "string.h"
#define MAX 10

int n; //图中的顶点数
int m; //颜色数
int a[6][6]; //邻接矩阵
int cn; //当前已着色顶点数
int sum = 0; //着色方案数
int x[MAX]; //x[i]=j表示第i个顶点用第j种颜色进行着色
int bestx[MAX];

int ok(int i) //检查当前结点所着颜色是否与前面的顶点冲突
{
int j;
for(j=1; j<=n; j++)
if((a[i][j]==1) && (x[i]==x[j])) //如果与图中顶点相邻,且着色相同
return 0; //则说明冲突
return 1;
}

//搜索到第i层,前i-1层已经着色
void backtrack(int i)
{
if(i>n) //如果搜索到叶结点
{
sum++; //着色方案数增加
int j;
for(j=1; j<=n; j++) //着色方案
bestx[j] = x[j];
}
else
{
int j;
for(j=1; j<=m; j++) //搜索m叉树,每一个结点都有m中颜色可选
{
x[i] = j; //为第i个结点着色
if(ok(i)==1) //检查当前结点所着颜色没有与前面的顶点冲突
backtrack(i+1); //为下一个顶点着色
x[i]=0;

}
}
}

void color(int a1[6][6], int n1, int m1)
{
n = n1;
m = m1;
int i, j;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
a[i][j] = a1[i][j];
for(i=1; i<=n; i++)
x[i] = 0;
backtrack(1);
}

int main()
{
int n1 = 5;
int m1 = 4;
int a1[6][6]={
{0, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 1, 0},
{0, 1, 0, 1, 1, 1},
{0, 1, 1, 0, 1, 0},
{0, 1, 1, 1, 0, 1},
{0, 0, 1, 0, 1, 0},
};
color(a1, n1, m1);
printf("邻接矩阵为:
");
int i, j;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
printf("%d ", a[i][j]);
printf("
");
}
printf("着色方案数为:%d
", sum);
return 0;
}

解决方案

关于图的m着色问题
图的M着色问题
m图着色问题

时间: 2024-11-02 21:04:57

回溯法-关于图的m着色问题的疑问的相关文章

C语言使用回溯法解旅行售货员问题与图的m着色问题_C 语言

旅行售货员问题 1.问题描述: 旅行售货员问题又称TSP问题,问题如下:某售货员要到若干个城市推销商品,已知各城市之间的路程(或旅费),他要选定一条从驻地出发,经过每个城市一遍最后回到驻地的路线,使总的路线(或总的旅费)最小.数学模型为给定一个无向图,求遍历每一个顶点一次且仅一次的一条回路,最后回到起点的最小花费. 2.输入要求: 输入的第一行为测试样例的个数T( T < 120 ),接下来有T个测试样例.每个测试样例的第一行是无向图的顶点数n.边数m( n < 12,m < 100 )

python 回溯法 子集树模板 系列 —— 10、m着色问题

问题 图的m-着色判定问题 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色,是否有一种着色法使G中任意相邻的2个顶点着不同颜色? 图的m-着色优化问题 若一个图最少需要m种颜色才能使图中任意相邻的2个顶点着不同颜色,则称这个数m为该图的色数.求一个图的最小色数m的问题称为m-着色优化问题. 分析 解的长度是固定的,n.若x为本问题的一个解,则x[i]表示第i个节点的涂色编号. 可以将m种颜色看作每个节点的状态空间.每到一个节点,遍历所有颜色,剪枝,回溯. 不难

python 回溯法 子集树模板 系列 —— 8、图的遍历

问题 一个图: A --> B A --> C B --> C B --> D B --> E C --> A C --> D D --> C E --> F F --> C F --> D 从图中的一个节点E出发,不重复地经过所有其它节点后,回到出发节点E,称为一条路径.请找出所有可能的路径. 分析 将这个图可视化如下: 本问题涉及到图,那首先要考虑图用那种存储结构表示.邻接矩阵.邻接表....都不太熟. 百度一下,在这里发现了一个最爱.

回溯法 -数据结构与算法

1.回溯法算法思想:   定义:         回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为"回溯点". 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能

读书时间--回溯法浅析:逆向思维领略算法之美

下面将使用回溯思想解决若干经典问题并通过它们来说明使用回溯的基本思路 什么叫回溯法 回溯是一种比较简单.比较常用的搜索策略. 它的基本思想是假设某问题的解决步骤可能有N步,且每一步的解决方法又可能有M种,那么就按照某种顺序依次试探每一步中的各种方法,一旦某一步的所有方法都失效,那么就返回上一步继续试探上一步骤的其他M−1种方法.简而言之就是从一条路往前走,能进则进,不能进则退回来,换一条路再试. 通常用回溯法解决问题的一般步骤为:首先,定义一个解空间,它包含问题的解,也就是每一步所采用的各种方法

算法——回溯法

回溯法 回溯法有"通用的解题法"之称.用它可以系统地搜索一个问题的所有解或任一解.回溯法是一种即带有系统性又带有跳跃性的搜索算法.它在问题的解空间树中,按深度优先策略,从根节点出发搜索解空间树.算法搜索至解空间树的任一结点时,先判断该节点是否包含问题的解.如果不包含,则跳过对以该节点为根的子树的搜索,逐层向其它祖先节点回溯.否则,进入该子树,继续按照深度优先策略搜索.回溯法求问题的所有解时,要回溯到根,且根节点的所有子树都已被搜索遍才结束.回溯法求问题的一个解时,只要搜索到问题的一个解

C++回溯法实例分析_C 语言

本文实例讲述了C++的回溯法,分享给大家供大家参考之用.具体方法分析如下: 一般来说,回溯法是一种枚举状态空间中所有可能状态的系统方法,它是一个一般性的算法框架. 解向量a=(a1, a2, ..., an),其中每个元素ai取自一个有限序列集Si,这样的解向量可以表示一个排列,其中ai是排列中的第i个元素,也可以表示子集S,其中ai为真当且仅当全集中的第i个元素在S中:甚至可以表示游戏的行动序列或者图中的路径. 在回溯法的每一步,我们从一个给定的部分解a={a1, a2, ..., ak}开始

算法详解之回溯法具体实现_C 语言

理论辅助: 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法.回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试.用回溯算法解决问题的一般步骤为: 1.定义一个解空间,它包含问题的解. 2.利用适于搜索的方法组织解空间. 3.利用深度优先法搜索解空间. 4.利用限界函数避免移动到不可能产生解的子空间. 问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性. 还是那个基调,不喜欢纯理论的东西,喜欢使用例子来讲诉理论,在算法系列总结:动态规划(

五大常用算法——分治法,动态规划,回溯法,分支界限法,贪心算法

分治算法一.基本概念    在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)--     任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个元素