题目

考虑DP。\(f(msk,i)\) 表示集合 \(msk(一定包含0号点)\) ,选了恰好i条边的连通方案数。转移用容斥,用这个点集内部所有连边方案减去不连通的。令\(|e_{msk}|\)表示两个端点都在集合msk内的边数,D为\(e_{\complement_{msk}sub}\)(sub在msk中补集内部的边集)。转移式:\(f(msk,i)=\binom{|e_{msk}|}{i}-\sum_{sub \in msk,0 \in sub,0 \leq j \leq i} f(sub,j)\cdot \binom{|D|}{i-j}\),其中sigma是枚举不连通情况中0号点所在的连通块。直接转移是\(O(3^nm^2)\)的,考虑优化。


我们枚举msk,现在需要计算\(f(msk,*)\)的值。观察转移式,后面一部分是\(\sum_{sub \in msk,0 \in sub,0 \leq j \leq i} f(sub,j)\cdot \binom{|D|}{i-j}\),枚举到\(f(sub,j)\)的时候,集合sub中的j条边已经确定要选了,我们现在要做的事就是依次决定sub外的\(|D|\)条边中哪些要选,如果有k条边选,就转移到\(f(msk,j+k)\)。

所以可以令\(g(i,j)\)表示已经有i条边确定要选,还有j条边“排队等待”决定。枚举所有可能转移到\(f(msk,*)\)的\(f(sub,j)\),让\(g(j,|D|)+=f(sub,j)\)。然后对\(g\)数组再做一次DP:

\[g(i-1,j+1)+=g(i,j),g(i-1,j)+=g[i][j]
\]

两个转移分别代表一条待定边选或不选。注意转移g的时候j要从大到小枚举。最后我们让\(f(msk,i)-=g[i][0]\)就行了。总复杂度\(O(3^nm+2^nm^2)\),常数很小可以通过。

注意自环的处理。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <LL,LL>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back using namespace std; const LL MOD=1000000007LL; LL qpow(LL x,LL a)
{
LL res=x,ret=1;
while(a>0)
{
if((a&1)==1) ret=ret*res%MOD;
a>>=1;
res=res*res%MOD;
}
return ret;
} LL n,m,in[33000],f[17000][210],g[210][210],fac[210],inv[210],cc[20];
vector <LL> gg[20]; LL C(LL nn,LL mm){return fac[nn]*inv[mm]%MOD*inv[nn-mm]%MOD;} struct SpanningSubgraphs
{
vector <int> count(int N,vector <int> A,vector <int> B)
{
fac[0]=1;repn(i,205) fac[i]=fac[i-1]*(LL)i%MOD;
rep(i,203) inv[i]=qpow(fac[i],MOD-2);
n=N;m=A.size();
rep(i,m) if(A[i]!=B[i])
{
gg[A[i]].pb(B[i]);
gg[B[i]].pb(A[i]);
}
LL cnt=0;
rep(i,m) if(A[i]==B[i])
{
++in[1<<A[i]];++cc[A[i]];
if(A[i]==0) ++cnt;
}
repn(i,(1<<n)-1)
{
int lowbit=(i&-i),id=__builtin_ctz(lowbit);
in[i]=in[i^(1<<id)]+cc[id];
rep(j,gg[id].size()) if((i&(1<<gg[id][j]))>0) ++in[i];
}
rep(i,cnt+1) f[0][i]=C(cnt,i);
repn(msk,(1<<(n-1))-1)
{
int lim=in[(msk<<1)|1];
rep(i,lim+2) rep(j,lim+2) g[i][j]=0;
for(int sub=msk;;sub=(sub-1)&msk)
{
if(sub!=msk)
{
rep(i,in[(sub<<1)|1]+1)
(g[i][in[(msk^sub)<<1]]+=f[sub][i])%=MOD;
}
if(sub==0) break;
}
rep(i,lim+1) for(int j=lim;j>0;--j) if(g[i][j]>0)
{
(g[i+1][j-1]+=g[i][j])%=MOD;
(g[i][j-1]+=g[i][j])%=MOD;
}
repn(j,lim) f[msk][j]=(C(lim,j)-g[j][0]+MOD)%MOD;
}
vector <int> ans;
for(int i=n-1;i<=m;++i) ans.pb(f[(1<<(n-1))-1][i]);
return ans;
}
};

最新文章

  1. 【原】npm 常用命令详解
  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统--系统模块部分图
  3. UI-UIImageView的图片填充方式(contentMode)_图片作为控件背景图的拉伸方式(stretch)介绍
  4. 使用eclipse maven遇到的错误(转)
  5. 短地址TinyURL的API使用
  6. 嵌入式 arm平台ping域名指定ip小结
  7. Head First 设计模式笔记:单例模式
  8. bootstrap 的 datetimepicker 结束时间大于开始时间
  9. HDOJ-ACM1014(JAVA)
  10. python类方法与对象方法学习
  11. @page指令 validateRequest的作用
  12. [UI列表]LoopScrollRect无限滑动不卡顿
  13. ES next &amp; Async Await
  14. 2018.11.06 bzoj1912: [Apio2010]patrol 巡逻(树形dp)
  15. UVAlive-7040 color(组合数学,二项式反演)
  16. H2Database聚合函数
  17. 深入浅出Android开发之Surface介绍
  18. checkbox多选框选择判断
  19. 《图解Http》 2-6章: 基础,报文,状态码,首部。
  20. 初识Java微信公众号开发

热门文章

  1. CF1709A Three Doors 题解
  2. 在docker容器中如何自动生成配置文件(以nginx配置为例)
  3. Go语言基础五:引用类型-切片和映射
  4. SpringCloud微服务实战——搭建企业级开发框架(四十五):【微服务监控告警实现方式二】使用Actuator(Micrometer)+Prometheus+Grafana实现完整的微服务监控
  5. 简单学习一下ibd数据文件解析
  6. 在django中前后端传输数据的编码格式(contentType)
  7. LuoguP4219 [BJOI2014]大融合(LCT)
  8. Java对象已死吗 深入理解Java虚拟机笔记
  9. 理想汽车 x JuiceFS:从 Hadoop 到云原生的演进与思考
  10. HDU6623 Minimal Power of Prime (简单数论)