hdu5713 K个联通块[2016百度之星复赛B题]
2016-05-29 22:52
225 查看
dp
代码
代码
#include<cstdio> const int N = 30000; const int P = 1000000009; int n,m,k,cnt ; long long f ,g ,o ,dp [15]; int e[15][15],i,j,l,a,b; int check(int x,int y) { int i; for (i=0;i<n;i++) if ((1<<i)==x) break; int tmp=i,ans=0; for (i=0;i<n;i++) if (((1<<i)|y)==y) ans+=e[tmp][i]; return ans; } int main() { int test; scanf("%d",&test); for (int ii=1;ii<=test;ii++) { scanf("%d%d%d",&n,&m,&l); o[0]=1;for (i=1;i<=500;i++) o[i]=o[i-1]*2%P; for (i=0;i<n;i++) for (j=0;j<n;j++) e[i][j]=0; for (i=1;i<=m;i++) { scanf("%d%d",&a,&b); a--;b--; e[a][b]++; if (a!=b) e[b][a]++; } for (i=1;i<(1<<n);i++) cnt[i]=cnt[i-(i&-i)]+check(i&-i,i); for (i=0;i<(1<<n);i++) f[i]=g[i]=0; for (i=1;i<(1<<n);i++) { j=i; do { j=((j-1)&i); if ((j|(i&-i))==j) g[i]=(g[i]+g[i-j]*f[j])%P; } while (j!=i); f[i]=(o[cnt[i]]-g[i])%P; (g[i]+=f[i])%P; } for (i=1;i<(1<<n);i++) for (k=1;k<=l;k++) dp[i][k]=0; dp[0][0]=1; for (i=1;i<(1<<n);i++) { for (k=1;k<=l;k++) { j=i; do { j=((j-1)&i); if ((j|(i&-i))==j) dp[i][k]=(dp[i][k]+dp[i-j][k-1]*f[j])%P; } while (j!=i); } } printf("Case #%d:\n%I64d\n",ii,(dp[(1<<n)-1][l]+P)%P); } }
相关文章推荐
- 个人冲刺——第六天
- 多线程-NSthread
- 剖析递归求二叉树高
- DNS 配置详解
- java数据结构之单链表
- 第十三周学习进度
- 新手建站需要知道的一些知识
- Chrome 离线版 并 安装报错0x80004002解决
- 求一组数的平均数(利用可变参数列表)
- c++中的顺序表写法,主要实现(增删查改,构造函数,运算符重载)
- c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)
- 小明哥教你使用模板函数实现顺序表
- [C++] 利用模板的模板参数实现单链表
- 初试-&gt;广义表
- 排序算法之插入排序
- 古典密码之hill密码的加密与解密程序实现
- 注释转换小项目(c注释-&gt;到c++注释)
- 浅析《大数据运算》-加减乘除以及模除运算
- 计算机视觉入门 Intorduction To Computer Vision
- 九九乘法表的C语言实现