算法之图的m着色问题

问题描述:给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。求解一种着色法,使得G中每条边上的2个顶点着色不同。

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

给定图G=(V,E)和m种颜色,如果该图是m可着色的,找出所有不同的着色方案。

问题分析:分析可知,该问题的解空间树是一棵完全m叉树,每一层中的每一结点都有m个儿子(即m种不同的着色方案)。

定义数组x[n]存储可行解,二维数组中元素a[i][j]表示顶点i和j是否连通(1连通0不连通)。

#include <iostream>
using namespace std;

int N=5,    //顶点个数
    M=4;    //颜色种类
int sum=0;  //可行解数量
int x[5]={-1,-1,-1,-1,-1};  //记录可行解
int a[5][5]={       //各顶点之间的连接关系
    /*0,1,1,1,0,
    1,0,1,1,1,
    1,1,0,1,0,
    1,1,1,0,1,
    0,1,0,1,0*/
    0,1,1,1,0,
    1,0,1,1,1,
    1,1,0,1,0,
    1,1,1,0,1,
    0,1,0,1,0
};

bool Ok(int k)  //判断是否满足条件(剪枝函数)
{
    for(int i=0;i<N;i++)
    {
        if(a[k][i]==1&&x[k]==x[i]&&x[i]!=-1)return false;
    }
    return true;
}

void Backtrack(int t)
{
    if(t>=N)    //到达叶子结点,记录一个可行解
    {
        sum++;
        for(int i=0;i<N;i++)
            cout<<x[i]+1<<" ";
        cout<<endl;
    }
    else
    {
        for(int i=0;i<M;i++)
        {
            x[t]=i;
            if(Ok(t))Backtrack(t+1);
            x[t]=-1;
        }
    }
}



int main()
{
    Backtrack(0);
    cout<<sum<<endl;
}

时间复杂度:O(m*n^2)

猜你喜欢

转载自blog.csdn.net/qq_35503380/article/details/80447019