图着色问题

图着色问题

首先来了解下图着色是什么?
给定无向连通图G=(V,E) 和 c种不同的颜色,用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果一个图最少需要c种颜色才能使图中每条边连接的2个顶点着不同颜色,则称c为该图的色数。

邻接矩阵
表示点与点之间是否有连线,用01表示。
.
接着是来看看图着色算法其中一种算法
回溯法(探索与回溯法),是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

求:给定图的顶点v,顶点间的边邻接关系graph[ ][ ],颜色的数量c,一共有多少种着色方法?
输入顶点数v,边数颜色数c,和该图的邻接矩阵graph[ ][ ]

算法实现步骤如下:

  1. 设置判断当前位置的颜色是否和相邻位置颜色重复函数为isSafe(int cur)
  2. isSafe,一个一个顶点遍历,符合坐标相邻且颜色相同则返回false,否则返回true
  3. 设置搜索函数backtrace(int cur)
  4. 先设置判断,如果当前搜索的顶点大于给定的定点数v,则着色方案加一。如果不大于,则继续进行搜索,给设定位置cur,尝试1-c的颜色,每尝试一次,使用isSafe函数判断是否成功,成功,则进行下一个位置cur+1的搜索,否则cur位置的颜色归0,开始回溯。
  5. 输出sum方案数。

分析时间复杂度:
最坏的情况:每一次isSafe都要检查V次,然后每个节点检查颜色,都要判断到C种,则时间复杂度为
O(mn)=O(n2)

源代码:

#include
using namespace std;
int v,e,graph[100][100];//v顶点数, e边数, graph图的邻接矩阵 
int c,color[100];//c颜色数  color当前边的颜色 
int sum = 0;//着色方法的数目 

//判断当前位置的颜色是否和相邻位置颜色重复 
bool isSafe(int cur)
{
    for(int i=1; i<=v; i++)
	{
        if(graph[cur][i] && color[cur] == color[i])
		{
//如果坐标(cur,i)相邻 且 cur的颜色和i的颜色相同 
            return false; 
        }
    }
    return true;
}

//开始搜索 
void backtrace(int cur)
{
    if(cur > v)
	{
        sum++;
    } 
	else 
	{
        for(int i=1; i<=c; i++)
		{//分别为cur位置尝试第i中颜色 
            color[cur] = i;//表示cur位置图上第i种颜色 
            if(isSafe(cur))
			{
                backtrace(cur+1);
            }
            color[cur] = 0;
        }
    }
}

int main()
{
    cout << "输入顶点数和颜色数量:" <<endl;
    cin >> v >> c;
    cout<< "输入邻接矩阵:" <<endl;
    for(int i=1; i<=v; i++)
	{
        for(int j=1; j<=v; j++)
		{
            cin >> graph[i][j];
        }
    }
    backtrace(1);
    cout << sum <<endl;
    return 0;
}

图着色问题_第1张图片

你可能感兴趣的:(图着色问题)