图的m着色问题

【题目描述】

给定无向连通图 G 和 M 种不同的颜色,用这些颜色为图 G 的各顶点着色,
每个顶点着一种颜色。如果有一种着色法使 G 中每条边的 2 个顶点着不同的颜
色,则称这个图是 M 可着色的。图的 M 着色问题是对于给定图 G 和 M 种颜色,
找出所有不同的着色法。
对于给定的无向连通图 G 和 M 种不同的颜色,编程计算图的所有不同的着色法。

【输入】

第一行有 3 个正整数 N,K 和 M,表示给定的图 G 有 N 个顶点和 K 条边,M 种
颜色。顶点编号为 1,2……,N。接下来的 K 行中,每行有 2 个正整数 U,V,
表示图 G 的一条边(U,V)。

数据范围:1

【输出】

不同的着色方案数

【样例输入】

5 8 4
1 2
1 3
1 4
2 3
2 4
2 5
3 4

4 5

【样例输出】

48

代码如下:

#include
using namespace std;
class Color
{
	friend void mcoloring(int n, int m, int** a);
private:
	bool isUsed(int t);
	void Backtrack(int i);
	int n; //顶点数
	int m; //颜色数
	int** a; //邻接矩阵
	int* x; //当前解
	long sum; //方案数
};
bool Color::isUsed(int t)
{
	for (int i = 1; i < t; i++)
		if (a[i][t] == 1 && x[i] == x[t])
			return false;
	return true;
}
void Color::Backtrack(int i)
{
	if (i > n)
	{
		sum++;
	}
	else
	{
		for (int j = 1; j <= m; j++)
		{
			x[i] = j;
			if (isUsed(i))
				Backtrack(i + 1);
			x[i] = 0;
		}
	}
}
void mcoloring(int n, int m, int **a)
{
	Color X;
	X.n = n;
	X.m = m;
	X.a = a;
	X.sum = 0;
	int* p = new int[n+1];
	for (int i = 1; i <= n; i++)
		p[i] = 0;
	X.x = p;
	X.Backtrack(1);
	delete[]p;
	cout << X.sum;
}
int main()
{
	int n, k, m;
	cin >> n >> k >> m;
	int k1, k2;
	int** a = new int* [n+1];
	for (int i = 1; i <= n; i++)
		a[i] = new int[n + 1];
	for (int i = 1; i <= k; i++)
	{
		cin >> k1 >> k2;
		a[k1][k2] = 1;
	}
	mcoloring(n, m, a);
	return 0;
}

 

你可能感兴趣的:(算法设计与分析,c++,回溯法)