這題當時搞不出,是問了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;
}