问题描述
给定无向连通图 G 和 m 种不同的颜色,用这些颜色为图 G的各顶点着色,每个顶点着一种颜色。如果有一种着色法使 G 中每条边的两个顶点着不同颜色,则称这个图是 m 可着色的。图的 m 着色问题是对于给定图 G 和 m 种颜色,找出所有不同的着色法。
输入描述
第 1 行有 3 个正整数(1≤n≤20)、k 和 (1≤m≤n),表示给定的图 G 有 n 个顶点、k条边、m 种颜色,顶点的编号为 1, 2,…,n 在接下来的 k行中每行有两个正整数 u, v,表示图 G的一条边(u,v)。
输出描述
程序运行结束时将计算出的不同着色方案数输出。
Tip: 不能着色输出 0 即可。
AC代码
#include<iostream>
using namespace std;
int k, v, m; //v 顶点 k 边数 m 颜色种类
int ans; //记录最后答案
int col[1010]; //标记每个顶点所图颜色
int graph[1010][1010]; //二维数组存图
bool judge(int p, int color) //判断p点是否能图该颜色
{
int i, flag = 1;
// 遍历与p点相邻接的点,如果p点所图颜色与这些点相同,那么p点就不能图这个颜色
for (i = 1; i <= v; i++)
{
if (graph[p][i] == 1 && color == col[i]) return false;
}
return true;
}
void dfs(int vec) //深搜,可理解为给vec这点图颜色
{
//如果当前所图的点的编号大于总共给的点的个数,那么说明此种图色方法可行
if (vec > v)
{
ans++;
return;
}
int i;
//遍历所有颜色,并判断是否能图这种颜色
for (i = 1; i <= m; i++)
{
if (judge(vec, i))
{
col[vec] = i;
dfs(vec + 1);
col[vec] = 0; //回溯
}
}
}
int main()
{
cin >> v >> k >> m;
int i;
for (i = 1; i <= k; i++)
{
int x, y;
cin >> x >> y;
graph[x][y] = 1; //注意是无向图
graph[y][x] = 1;
}
dfs(1); //从顶点1开始图色
cout << ans << endl;
return 0;
}
萌新上路,欢迎指出问题或者提出好的想法
其他已经做完的题目的代码已经上传github,欢迎查看
https://github.com/JZP1112/suan-fa-she-ji-yu-fen-xi.git