这题当时搞不出,是问了CrazyBoy的, 超级膜拜。 他的代码超级漂亮
题意:给出一个无向图n<=12 , 一些节点已经着了颜色,问用k<=12种颜色对图染色的方案数(相邻点不能同色)
他是用Dp做的,前i种颜色染整个图的方案数
转移是枚举一个集合染第i种颜色
/**//*
2010 Fuzhou Warm up
D grap coloring
Author : CrazyBoy (Jin Bin)
*/
#include<cstdio>
#include<cstring>
int color[12];
int G[12];
long long wys[1 << 12] , nwys[1 << 12];
int main()
{
int T , n , m , colors;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d", &n, &m, &colors);
memset(G, 0, sizeof(G));
memset(color, 0, sizeof(color));
for(int i = 0 ; i < n ; i++)
{
int nowc;
scanf("%d", &nowc);
if(nowc != 0 )
{
nowc --;
color[nowc] |= 1 << i;
}
}
for(int i = 0; i < m ; i ++)
{
int a, b ;
scanf("%d%d",&a, &b);
G[a] |= 1 << b;
G[b] |= 1 << a;
}
int MASK = (1 << n) - 1;
memset(wys, 0, sizeof(*wys) << n );
wys[0] = 1;
for(int i = 0; i < colors; i ++)
{
memset(nwys, 0, sizeof(*nwys) << n );
for(int msk = 0; msk <= MASK; msk ++)
{
if(~msk & color[i])
continue;
bool found = false;
for(int j = 0; j < n; j ++)
if(msk >> j & 1 && msk & G[j])
{
found = true;
break;
}
if(found)
continue;
int MASK2 = MASK ^ msk;
int j = 0;
do {
nwys[j | msk] += wys[j];
}while(j = j - MASK2 & MASK2);
}
memcpy(wys, nwys, sizeof(*wys) << n);
}
printf("%lld\n",wys[MASK]);
}
return 0;
}