1.问题
最大团:求一张无向图的最大团。团的定义:给定图G=(V,E),其中,V={1,…,n}是图G的顶点集,E是图G的边集,图G的团就是一个两两之间有边的顶点集合,团是G的一个完全子图。如果一个团不被其他任一团所包含,即它不是其他任一团的真子集,则称该团为图G的极大团(maximal clique)。顶点最多的极大团,称之为图G的最大团(maximum clique)——来源于百度百科
图的m着色问题:给定一个无向图G=(V, E),其中V为顶点集合,E为边集合,图着色问题即为将V分为K个颜色组,每个组形成一个独立集,即其中没有相邻的顶点。
2.解析
最大团:
思路:采用分支界限的方法,个人理解就是对图进行DFS,不过需要抽象成树的形式。首先确定最大团问题的解空间,对于一个最大团来说,对每个结点只有取和不取两种情况,所以就可以抽象成一棵二叉树,左子树代表取,右子树代表不取,再确定分支界限进行剪枝。
具体实例:定义cn:当前团结点数;bestn:最大团结点数;n:总结点数;m:总边数,i为当前结点,不难推出分支上界是cn+n-i>=bestn,因为如果已有团的结点数+即将加入团中的结点数都小于已知最大团的结点个数,那这个分支也就没有继续深入的必要,所以这就是最大团的分支上界。
例子:
图的m着色问题:
思路:采用分支界限的方法,个人理解就是对图进行DFS,不过需要抽象成树的形式。首先确定着色问题的解空间,对于一个点来说,对每个结点有m种染色情况,所以就可以抽象成一棵m叉树.
具体实例:color[]:结点染几号颜色;OK:是否存在染色方案
例子:
思考方式和最大团类似,因可行方案过多,这里不再赘述,同时上界函数不明显,所以还会更简单一点.
3.设计
最大团:
int cn, bestn, n, m;//cn:当前团结点数;bestn:最大团结点数;n:总结点数;m:总边数
int mp[MAXN][MAXN];//无向图
bool used[MAXN];//标记是否处在当前团
void DFS(int i)
{
bool flag = false;
if (i > n) //输出最大团
{
bestn = cn;
for (int j = 1; j <= n; j++)
if (used[j]