给图的顶点着色


给出一个无向图和一个数字m,此数字代表了允许使用颜色的种类,判断是否至多可以应用m种颜色,将图的每个顶点着色,并且相邻节点着的颜色不同。

      输入:

      1, 二维矩阵 graph[V][V],其中V代表图中顶点的个数,而矩阵本身是图的邻接矩阵表示形式。

      2,对于graph[V][V]的理解是,graph[i][j], 如果i==j,那么graph[i][j]为1,或者i!= j,但是从顶点i到j有一条边

      输出:

      返回一个一位数组color[V], color[i] 的取值范围是1-m,代表第i个顶点图的颜色,同时要说明给定的矩阵是否可以被m涂色而且每两个相邻的节点颜色不同。


      采用的方法应该是回溯算法:

      算法的基本思想是,对于每个不同的节点,依次进行着色,在试图着色之后要进行判断,判断此节点的已经着色的临接节点中是否有和它着相同颜色的,如果有,那么此节点放弃当前的着色,改试使用其他颜色,最终,如果每一种颜色对此节点都不适用,那么就返回false,说明此图不能应用m种颜色对每个节点都着色而且每对相邻节点都能着不同的颜色。相反,如果此节点着以某种颜色能够满足与它邻接点颜色不一样的话,那么尝试对下一个节点着色,直至所有节点都被着色,而且每对邻接点的颜色都不一样,那我们就成功了。给定一个例子图如下:


给定解决方案代码如下,并且说明,对于一个图来说会有不止一个解决方案:

#include<iostream>
using namespace std;

const int V = 4;

void printSolution(int color[]) {
	cout << "there existing solutions:" << endl;
	int i;
	for (i = 0; i < V; i++)
		cout << color[i] << " ";
}

bool isSafe(int v, bool graph[V][V], int color[], int c) {
	int i;
	for (i = 0; i < V; i++)
		if (graph[v][i] && c == color[i])
			return false;
	return true;
}

bool graphColoringUtil(bool graph[V][V], int m, int color[], int v) {
	if (v == V)
		return true;
	int c;
	for (c = 1; c <= m; c++) {
		if (isSafe(v, graph, color, c)) {
			color[v] = c;
			if (graphColoringUtil(graph, m, color, v + 1)) 
				return true;
			else
				color[v] = 0;
		}
	}
	return false;
}

bool graphColoring(bool graph[V][V], int m) {
	int *color = new int[V];
	int i;
	for (i = 0; i < V; i++)
		color[i] = 0;
	if (false == graphColoringUtil(graph, m, color, 0)) {
		cout << "does not exist solution." << endl;
		return false;
	}
	printSolution(color);
	delete []color;
	return true;
}

int main(int argc, char *argv[]) {
	bool graph[V][V] = {{1, 1, 1, 1},
        {1, 1, 1, 0},
        {1, 1, 1, 1},
        {1, 0, 1, 1},
    };
    int m = 3; // Number of colors
    graphColoring(graph, m);
	cin.get();
    return 0;
}


  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值