hdu5713 K个联通块[2016百度之星复赛B题]
dp
代码
1 #include<cstdio> 2 const int N = 30000; 3 const int P = 1000000009; 4 int n,m,k,cnt[N]; 5 long long f[N],g[N],o[N],dp[N][15]; 6 int e[15][15],i,j,l,a,b; 7 int check(int x,int y) 8 { 9 int i; 10 for (i=0;i<n;i++) 11 if ((1<<i)==x) break; 12 int tmp=i,ans=0; 13 for (i=0;i<n;i++) 14 if (((1<<i)|y)==y) 15 ans+=e[tmp][i]; 16 return ans; 17 } 18 int main() 19 { 20 int test; 21 scanf("%d",&test); 22 for (int ii=1;ii<=test;ii++) 23 { 24 scanf("%d%d%d",&n,&m,&l); 25 o[0]=1;for (i=1;i<=500;i++) o[i]=o[i-1]*2%P; 26 for (i=0;i<n;i++) 27 for (j=0;j<n;j++) 28 e[i][j]=0; 29 for (i=1;i<=m;i++) 30 { 31 scanf("%d%d",&a,&b); 32 a--;b--; 33 e[a][b]++; 34 if (a!=b) 35 e[b][a]++; 36 } 37 for (i=1;i<(1<<n);i++) 38 cnt[i]=cnt[i-(i&-i)]+check(i&-i,i); 39 for (i=0;i<(1<<n);i++) 40 f[i]=g[i]=0; 41 for (i=1;i<(1<<n);i++) 42 { 43 j=i; 44 do 45 { 46 j=((j-1)&i); 47 if ((j|(i&-i))==j) 48 g[i]=(g[i]+g[i-j]*f[j])%P; 49 } 50 while (j!=i); 51 f[i]=(o[cnt[i]]-g[i])%P; 52 (g[i]+=f[i])%P; 53 } 54 for (i=1;i<(1<<n);i++) 55 for (k=1;k<=l;k++) 56 dp[i][k]=0; 57 dp[0][0]=1; 58 for (i=1;i<(1<<n);i++) 59 { 60 for (k=1;k<=l;k++) 61 { 62 j=i; 63 do 64 { 65 j=((j-1)&i); 66 if ((j|(i&-i))==j) 67 dp[i][k]=(dp[i][k]+dp[i-j][k-1]*f[j])%P; 68 } 69 while (j!=i); 70 } 71 } 72 printf("Case #%d:\n%I64d\n",ii,(dp[(1<<n)-1][l]+P)%P); 73 } 74 }