给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的。图的m着色问题是对于给定图G和m种颜色,找出所有不同的着色法。
第1行有3个正整数n,r 和m(n < 20,r < 200,m < 10),表示给定的图G有n个顶点和r条边,m种颜色。顶点编号为0,1,2,…,n-1。接下来的k行中,每行有2个正整数u,v,表示图G 的一条边(u,v)。
输出不同的着色方案的总数。
3 2 2
0 1
1 2
2
#include
#include
int a[20][20],color[10];
int n, r, m,sum;
int check_color ( int k, int s )
{
int i;
for ( i = 0; i < n; i++ )
if ( a[k][i] == 1 && color[i] == s )//有邻接关系并且着相同颜色
return 0;
return 1;
}
void put_color ( int k )
{
int s;
if ( k == n )//全部涂完
sum++;
else
{
for ( s = 1; s <= m; s++ )
if ( check_color ( k, s ) )
{
color[k] = s;
put_color ( k + 1 );
color[k] = 0;
}
}
}
int main()
{
int i, j, x, y;
scanf ( "%d%d%d", &n, &r, &m );
for ( i = 0; i < n; i++ )
{
for ( j = 0; j < n; j++ )
a[i][j] = 0;
color[i]=0;
}
for ( i = 0; i < r; i++ )
{
scanf ( "%d%d", &x, &y );
a[x][y] = 1;
a[y][x] = 1;
}
put_color ( 0 );
printf("%d\n",sum);
return 0;
}
此题是回溯算法中十分经典的一道题,数组下标的处理是关键:
解题过程中用到了无向图的邻接矩阵的构造,将处于同一条边的两个顶底构成的数组元素标记为1,其他为0。
- 由于所有顶点的标记是从0开始的,所以构造邻接矩阵时一定也是从下标为0的地方开始,后面循环的时候,也要注意0这个位置。
- 主函数中第一次调用put_color函数也是从0开始,不能想当然从1开始。