Codeforces53E Dead Ends Matrix_Tree定理 容斥原理
来源:互联网 发布:考研数学辅导书 知乎 编辑:程序博客网 时间:2024/06/06 11:40
题意:给出一个n个点的无向图,求恰好有k个叶子的生成树个数 n<=10
Sol:
如果是完全图,n个点的带标号生成树个数为n^{n-2} 可以用矩阵树定理或者打表+oeis证明
那么在完全图上求恰好k个叶子的生成树就考虑容斥,钦定有几个点一定是叶子,剩下的点用公式算,每个钦定的叶子都可以接在非钦定的点下面,乘起来在乘个组合数就行,复杂度可以做到O(nlogn) log是快速幂的复杂度
现在给出图的形态了,也可以考虑容斥,枚举钦定叶子的集合,剩下的点生成树个数可以用矩阵树定理算,钦定的点的方案也可以算,记录F(i)表示i集合的方案数
然后容斥就可以对于每个集合枚举包含包含她的集合,加加减减就可以了,枚举集合可以枚举补集的子集再或上现在的集合
总复杂度O(2^n*n^3+3^n)
因为矩阵树定理算行列式要高斯消元,精度问题还是有的,一开始不四舍五入一直过不去
Code:
#include<bits/stdc++.h>#define debug(x) cout<<#x<<"="<<x<<endl#define cls(x) memset(x,0,sizeof x)typedef long long ll;using namespace std;const int maxn = 12;const double eps = 1e-6;int n,m,tar;vector<int> line[maxn];ll f[1<<maxn];int idx[maxn];bool ok[maxn];double a[maxn][maxn];ll ans;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}int count(int x){int res=0;while(x){if(x&1)res++;x>>=1;}return res;}double gauss(int len){double res=1;for(int i=1;i<=len;i++){int now=i;while(now<=len&&fabs(a[now][i])<=eps) now++;if(now>len) continue;if(now!=i) for(int j=1;j<=len;j++) swap(a[now][j],a[i][j]);double tmp=a[i][i];res*=tmp;for(int j=1;j<=len;j++) a[i][j]/=tmp;for(int j=1;j<=len;j++) if(i!=j){tmp=a[j][i];for(int k=1;k<=len;k++) a[j][k]-=tmp*a[i][k];}}for(int i=1;i<=len;i++) res*=a[i][i];return round(res);}ll calc(int sta){int cnt=count(sta),now=0;if(cnt<tar) return 0;cls(a);cls(ok);for(int i=1;i<=n;i++) if(!(sta&(1<<i>>1))) ok[i]=1,idx[i]=++now;for(int i=1;i<=n;i++) if(ok[i]){int sz=line[i].size();for(int j=0;j<sz;j++){int w=line[i][j];if(ok[w]) a[idx[i]][idx[w]]-=1.0,a[idx[i]][idx[i]]+=1.0;}}ll res=1;for(int i=1;i<=n;i++) if(!ok[i]){int tmp=0,sz=line[i].size();for(int j=0;j<sz;j++) if(ok[line[i][j]]) tmp++;res*=tmp;}return res*gauss(now-1);}int main(){n=read();m=read();tar=read();for(int i=1;i<=m;i++){int x=read(),y=read();line[x].push_back(y);line[y].push_back(x);}int mr=(1<<n)-1;for(int i=1;i<=mr;i++) f[i]=calc(i);for(int i=1;i<=mr;i++){if(count(i)!=tar) continue;int sta=mr-i;for(int s=sta;s;s=(s-1)&sta){if(count(s)&1) ans-=f[i+s];else ans+=f[i+s];}ans+=f[i];}cout<<ans<<endl;return 0;}
阅读全文
1 0
- Codeforces53E Dead Ends Matrix_Tree定理 容斥原理
- BZOJ4596 黑暗前的幻想乡 Matrix_Tree定理 容斥原理
- hdu 3929 Big Coefficients(Lucas定理+容斥原理)
- HDU 5768 (Lucky7 中国剩余定理+容斥原理)
- [2016ACM多校] HDU5768 容斥原理 中国剩余定理
- hdu 5768 中国剩余定理 + 容斥原理
- HDU 5768Lucky7-中国剩余定理+容斥原理
- HDU 5768 Lucky7(中国剩余定理+容斥原理)
- hdu 5768 Lucky7 容斥原理 中国剩余定理
- hdu5768 Lucky7 中国剩余定理 + 容斥原理
- poj2773 —— 二分 + 容斥原理 + 唯一分解定理
- 数论 + 容斥定理
- HDU4407Sum 容斥定理
- uva11806(容斥定理)
- 容斥定理
- 容斥定理
- 容斥定理
- POJ_3904_Sky_Code 容斥定理
- 通过okhttp3下载文件实现APP版本更新
- Winform程序安装后打开出现程序停止运行问题解决方法
- PE文件格式详解(3)
- 士兵杀敌(三)
- 不能读取变量的length属性
- Codeforces53E Dead Ends Matrix_Tree定理 容斥原理
- RedHat7安装JDK1.8
- 3、操作系统内存管理——段页式(虚拟内存)
- 存储过程+事务
- TCP协议3次握手
- 学Java过程中最重要的8幅图,资深程序员都知道重要性
- 【JavaSE笔记】IO(二)File类
- Java中反射及动态编译
- Android 使用逐帧动画找不到标签