這題當時搞不出,是問了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, 
0sizeof(G));
        memset(color, 
0sizeof(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, 
0sizeof(*wys) << n );
        wys[
0= 1;
        
for(int i = 0; i < colors; i ++)
        
{
            memset(nwys, 
0sizeof(*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;
}