[HDU5713]K个联通块

题目大意:

有一张\(n(n\le14)\)个点,\(m\)条边无重边的无向图,求有多少个边集,使得删掉边集里的边后,图里恰好有\(k\)个连通块。

思路:

一个显然的动态规划是,\(f_{s,i}\)表示点集为\(s\),分成\(i\)个连通块的方案数。

转移什么的都很显然,关键是如何求\(f_{s,1}\)。(万事开头难!)

\(f_{s,1}\)的含义是删去\(s\)中若干条边使得新图仍然连通的方案数。我们可以将其转化为任意删边的方案数-删边使得该图不连通的方案数。

而后者就相对好求。

源代码:

#include<cstdio>
#include<cctype>
#include<cstring>
#include<numeric>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=14,M=105,mod=1e9+9;
struct Edge {
int u,v;
};
Edge e[M];
int f[1<<N][N+1],cnt[1<<N];
inline int power(int a,int k) {
int ret=1;
for(;k;k>>=1) {
if(k&1) ret=(int64)ret*a%mod;
a=(int64)a*a%mod;
}
return ret;
}
inline int inv(const int &x) {
return power(x,mod-2);
}
inline int lowbit(const int &x) {
return x&-x;
}
int main() {
const int T=getint();
for(register int i=1;i<=T;i++) {
memset(f,0,sizeof f);
memset(cnt,0,sizeof cnt);
const int n=getint(),m=getint(),k=getint();
int tmp=0;
for(register int i=0;i<m;i++) {
e[i]=(Edge){getint()-1,getint()-1};
if(e[i].u==e[i].v) tmp++;
}
for(register int i=0;i<n;i++) f[1<<i][1]=1;
for(register int s=0;s<1<<n;s++) {
if(__builtin_popcount(s)<=1) continue;
for(register int i=0;i<n;i++) {
if((s>>i)&1) {
for(register int j=0;j<m;j++) {
const int &u=e[j].u,&v=e[j].v;
if(u==v) continue;
if(i==u&&((s>>v)&1)) cnt[s]++;
if(i==v&&((s>>u)&1)) cnt[s]++;
}
}
}
cnt[s]>>=1;
const int v=s^lowbit(s);
for(register int t=(v-1)&v;;t=(t-1)&v) {
(f[s][1]+=(int64)f[t^lowbit(s)][1]*power(2,cnt[s^t^lowbit(s)])%mod)%=mod;
if(!t) break;
}
f[s][1]=(power(2,cnt[s])-f[s][1]+mod)%mod;
}
for(register int j=2;j<=k;j++) {
for(register int s=1;s<1<<n;s++) {
for(register int t=(s-1)&s;t;t=(t-1)&s) {
(f[s][j]+=(int64)f[t][j-1]*f[s^t][1]%mod)%=mod;
}
f[s][j]=(int64)f[s][j]*inv(j)%mod;
}
}
printf("Case #%d:\n%lld\n",i,(int64)f[(1<<n)-1][k]*power(2,tmp)%mod);
}
return 0;
}

[HDU5713]K个联通块的更多相关文章

  1. hdu5713 K个联通块[2016百度之星复赛B题]

    dp 代码 #include<cstdio> ; ; int n,m,k,cnt[N]; ]; ][],i,j,l,a,b; int check(int x,int y) { int i; ...

  2. 树上第k大联通块

    题意:求树上第k大联通块 n,k<=1e5 考虑转化为k短路的形式. 也就是要建出一张图是的这条图上每一条S到T的路径都能代表一个联通块. 点分治建图 递归下去,假定每个子树的所有联通块中都可以 ...

  3. K个联通块

    题意: 有一张无重边的无向图, 求有多少个边集,使得删掉边集里的边后,图里恰好有K个联通块. 解法: 考虑dp,$h(i,S)$表示有$i$个联通块,点集为$S$的图的个数,$g(S)$表示点集为S的 ...

  4. 【HDOJ5713】K个联通块(状压DP,计数)

    题意:有一张无重边的无向图, 求有多少个边集,使得删掉边集里的边后,图里恰好有K个连通块. 1≤T≤201≤K≤N≤140≤M≤N∗(N+1)/21≤a,b≤N 思路:From http://blog ...

  5. Codeforces 731C. Socks 联通块

    C. Socks time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard input o ...

  6. Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量

    D. Directed Roads   ZS the Coder and Chris the Baboon has explored Udayland for quite some time. The ...

  7. Educational Codeforces Round 5 - C. The Labyrinth (dfs联通块操作)

    题目链接:http://codeforces.com/contest/616/problem/C 题意就是 给你一个n行m列的图,让你求’*‘这个元素上下左右相连的连续的’.‘有多少(本身也算一个), ...

  8. [洛谷P1197/BZOJ1015][JSOI2008]星球大战Starwar - 并查集,离线,联通块

    Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过 ...

  9. PAT A1013 Battle Over Cities (25 分)——图遍历,联通块个数

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

随机推荐

  1. Linux quotacheck失败

    我找了多少个帖子才发现解决这个问题的啊...最终还是靠FQ找的这位大佬的文章  http://www.2daygeek.com/quotacheck-error/# 当我在执行quotacheck - ...

  2. [iOS]Xcode处理过时方法的警告

    ####强迫症的福利, 有的时候, 我们特别讨厌Xcode中的代码警告, 以下就是遇到各种警告的时候的处理方法:(后续会一直更新) 产生警告的原因: 某些方法废弃了, 会产生警告! 样式: 处理方法: ...

  3. JavaScript继承详解(三)

    在第一章中,我们使用构造函数和原型的方式在JavaScript的世界中实现了类和继承, 但是存在很多问题.这一章我们将会逐一分析这些问题,并给出解决方案. 注:本章中的jClass的实现参考了Simp ...

  4. CSS-3 RGBA的使用

    由于IE-8及以下都不支持 RGBA(),所以往往大家都不用这个属性,而是用图层叠加的方式去实现我们想要的效果.因为 opacity 这个属性是会影响到子孙元素的. 例如: <div class ...

  5. 20155218 2016-2017-2 《Java程序设计》第7周学习总结

    20155218 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 就目前来说,即使标注为GMT(无论是文件说明,或者是API的日期时间字符串描述),实际上谈到 ...

  6. mysql内连接、左连接、右连接

    内连接(INNER JOIN)(典型的连接运算,使用像   =   或   <>   之类的比较运算符).包括相等连接和自然连接. 内连接使用比较运算符根据每个表共有的列的值匹配两个表中的 ...

  7. 【干货】查看windows文件系统中的数据—利用簇号查看文件与恢复文件

    前面我们使用这个软件发现了很多删除掉的数据,今天来看看簇.FAT文件系统中,存在一个簇的链接,我知道了簇1在哪里就可以顺藤摸瓜恢复所有的信息. 这里使用FAT 12为例子,FAT其他万变不离其宗,甚至 ...

  8. win7下iis中配置php.ini文件

    将php.ini-development配置文件重命名为php.ini配置文件即可. 接着做如下配置操作: 1.修改php.ini配置文件 打开php.ini配置文件,找到 12 ; On windo ...

  9. java多线程计算和

    如题:如何利用多线程实现1~1000000000的和 本文利用Callable可以返回值的特性,并将执行结果用CompletionService进行存储,最后将分步值累加. import java.u ...

  10. Pandas DataFrame数据的增、删、改、查

    Pandas DataFrame数据的增.删.改.查 https://blog.csdn.net/zhangchuang601/article/details/79583551 #删除列 df_2 = ...