回溯法 图着色问题

用尽量少的颜色为下面这个图的每个节点着色, 要求相连的节点颜色不一样


#include <iostream>
#include <memory.h>
#define COLOR_COUNT 3
bool graph[100][100];		// 点的编号从1开始
int colors[100] = { 0 };	// 每个点已经选择的颜色, 默认0
int point_count;

// 对c节点及其子节点尝试每一种着色方案
void dg(int c) {
	if (c == point_count + 1) {
		for (int i = 1; i <= point_count; ++i) {
			printf("%d ", colors[i]);
		}
		printf("\n");
		return;
	}
	// 找到与该节点相连的点用过的颜色
	bool* flag = new bool[COLOR_COUNT + 1];
	memset(flag, false, (COLOR_COUNT + 1) * sizeof(bool));
	for (int i = 1; i < c; ++i) {
		if (graph[c][i] && colors[i]) {
			flag[colors[i]] = true;
		}
	}
	// 依次尝试每一种颜色
	for (int i = 1; i <= COLOR_COUNT; ++i) {
		if (flag[i]) continue;	// 如果颜色被用过 取消
		colors[c] = i;			// 使用颜色i
		dg(c + 1);				// 递归
		colors[c] = 0;			// 取消颜色
	}
	delete[] flag;
}

int main() {
	memset(graph, false, sizeof(graph));
	scanf("%d", &point_count);
	int edge_connt;
	scanf("%d", &edge_connt);
	for (int i = 0; i < edge_connt; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		graph[a][b] = true;
		graph[b][a] = true;
	}
	dg(1);
	return 0;
}

输入

5
7
1 2
1 5
1 4
2 5
2 3
3 4

4 5

5个点, 7条边, 然后是7条边的两端

运行结果



这样求出来的解有12个; 但是这三个颜色可以等价替换. 如果颜色两两交换可以当做没有差异, 则


实际只有两个方案

猜你喜欢

转载自blog.csdn.net/u010099177/article/details/80572851