题链:

http://www.lydsy.com/JudgeOnline/problem.php?id=4596

题解:

容斥,矩阵树定理,矩阵行列式

先说说容斥:(一共有 N-1个公司)
令 f[i] 表示选出 (N-1)-i 个公司来修路(即有i个公司一定不修),且不管每个公司只能修一条路这一限制的方案数。
那么 答案 ANS=0个公司不修的方案数 - 1个公司不修的方案数 +2个公司不修的翻案数 ...
即 ANS= f[0] - f[1] +f[2] - ... + (-1)i*f[i]
f[i]的求法呢,就是先O(2N)枚举公司集合情况,
然后用矩阵树定理 O(N3) 求出当前情况下的生成树方案数。
另外再本题中,在构造上三角矩阵用以求行列式时,
既要避免小数,还要不影响原矩阵的行列式的值,
所以采用辗转相除的高斯消元法去构造上三角矩阵。复杂度多一个(logN)
由矩阵行列式的性质可知,这样辗转相除的高斯消元法不会影响行列式的绝对值,
只会影响符号位的正负,所以统计一下正负号的变化就好了。
(还不会矩阵树定理,看看这里,入门一波。)
所以总的时间复杂度为 O(2N*N3*logN)。
(都是这个复杂度,不晓得为什么我的代码跑到这么慢,都垫底了......)

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define add(x,y) (((1ll*(x)+(y))%mod+mod)%mod)
#define mul(x,y) (((1ll*(x)*(y))%mod+mod)%mod)
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
using namespace std;
const int mod=1000000007;
struct Matrix{int Val[20][20],*X[20],R,C;void Init(int r,int c){//r==cR=r; C=c;memset(Val,0,sizeof(Val));for(int i=1;i<=R;i++) X[i]=Val[i];}void Modify(int r,int c,int v){X[r][c]=add(X[r][c],v);}void operator =(const Matrix &rtm){Init(rtm.R,rtm.C);for(int i=1;i<=R;i++)for(int j=1;j<=C;j++)Val[i][j]=rtm.X[i][j];}Matrix operator -(const Matrix & rtm) const{Matrix now; now=*this;for(int i=1;i<=R;i++)for(int j=1;j<=C;j++)now.X[i][j]=add(now.X[i][j],-rtm.X[i][j]);return now;}void Gauss_Euclidean(int p,int &ti){//形成上三角矩阵 if(p==R-1) return;if(!X[p][p]) for(int i=p+1;i<R;i++) if(X[i][p]){swap(X[i],X[p]); ti++; break;}if(!X[p][p]) return;for(int i=p+1;i<R;i++){while(X[i][p]){int t=X[p][p]/X[i][p];for(int j=p;j<R;j++)X[p][j]=add(X[p][j],-mul(X[i][j],t));swap(X[p],X[i]); ti++;}}Gauss_Euclidean(p+1,ti);}int Determinant(){int ti=0,ans=1;Gauss_Euclidean(1,ti);for(int i=1;i<R;i++) ans=mul(ans,X[i][i]);if(ti&1) ans=mul(ans,-1);return ans;}void print(){for(int i=1;(i!=1?printf("\n"):0),i<=R;i++)for(int j=1;j<=R;j++)printf("%d ",X[i][j]);}
}A,B,K;
int cpy[20][500];
int ANS,N,tmp;
void dfs(int p,int num){if(p>=N) return;//选for(int i=1,a,b;i<=2*cpy[p][0];i+=2){a=cpy[p][i]; b=cpy[p][i+1];A.Modify(a,a,1); A.Modify(b,b,1);B.Modify(a,b,1); B.Modify(b,a,1);}K=A-B; tmp=K.Determinant();if(((N-1)-(num+1))&1) tmp=mul(tmp,-1);ANS=add(ANS,tmp);dfs(p+1,num+1);//不选for(int i=1,a,b;i<=2*cpy[p][0];i+=2){a=cpy[p][i]; b=cpy[p][i+1];A.Modify(a,a,-1); A.Modify(b,b,-1);B.Modify(a,b,-1); B.Modify(b,a,-1);}dfs(p+1,num);
}
int main()
{scanf("%d",&N);A.Init(N,N); B.Init(N,N);for(int i=1;i<=N-1;i++){scanf("%d",&cpy[i][0]);for(int j=1;j<=2*cpy[i][0];j++)scanf("%d",&cpy[i][j]);}dfs(1,0);printf("%d",ANS);return 0;
}

转载于:https://www.cnblogs.com/zj75211/p/8035125.html

●BZOJ 4596 [Shoi2016]黑暗前的幻想乡相关推荐

  1. bzoj 4596: [Shoi2016]黑暗前的幻想乡

    这个题貌似奶了一口trump,,, 本来看到一个公司一条边,而且N是那么科学,肯定要容斥了,然后蛋疼的想应该怎么求生成树.. 本来一开始乱说了个矩阵树定理,然而忘了,就像奇奇怪怪的东西了..然并卵,正 ...

  2. Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理,子集反演)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Luogu P4336 [SHOI2016]黑暗前的幻想乡(容斥,矩阵树定理) Problem n≤1 ...

  3. P4336 [SHOI2016]黑暗前的幻想乡

    题目 P4336 [SHOI2016]黑暗前的幻想乡 做法 每种颜色恰好一条边,有点难处理啊 根据套路,数据范围这么小,容斥一下所有的情况就可以了 对每种颜色进行状压,表这次只能选这些颜色,做\(n- ...

  4. 【BZOJ4596】[Shoi2016]黑暗前的幻想乡 容斥+矩阵树定理

    [BZOJ4596][Shoi2016]黑暗前的幻想乡 Description 幽香上台以后,第一项措施就是要修建幻想乡的公路.幻想乡有 N 个城市,之间原来没有任何路.幽香向选民承诺要减税,所以她打 ...

  5. [BZOJ4596][Shoi2016]黑暗前的幻想乡-Matrix Tree 矩阵树定理

    黑暗前的幻想乡 Description 四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖怪涌入了幻想乡,扰乱了幻想乡昔日的秩序.但是幻想乡的建制派妖怪(人类)博丽灵梦和八云紫等人整日 ...

  6. BZOJ4596:[SHOI2016]黑暗前的幻想乡——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4596 https://www.luogu.org/problemnew/show/P4336#su ...

  7. SHOI2016 黑暗前的幻想乡

    题目链接:戳我 幻想乡是个什么东西??(逃 矩阵树定理+容斥 就是设\(dp[i]\)表示至多i个公司修建道路,那么我们有\(ans=dp[n-1]-dp[n-2]+dp[n-3]......\)ba ...

  8. [luogu3244 SHOI2016] 黑暗前的幻想乡(容斥原理+矩阵树定理)

    传送门 Description 给出 n 个点和 n−1 种颜色,每种颜色有若干条边.求这张图多少棵每种颜色的边都出现过的生成树,答案对 109+7 取模. Input 第一行包含一个正整数 N(N& ...

  9. 洛谷 P4336 [SHOI2016] 黑暗前的幻想乡 题解

    前置芝士 Kirchhoff 矩阵树定理 Kirchhoff矩阵树定理解决了一个问题:对于一个确定的无向图,其究竟有多少个生成树? 对于一个无向图,我们拥有其邻接矩阵 A\bf{A}A. 这里的邻接矩 ...

最新文章

  1. Java中static关键字总结
  2. FluentNhibernate 的数据库连接的配置
  3. 【转】匈牙利命名法(Hungarian Notation)
  4. 浏览器从输入URL到页面渲染过程 —— 浏览器的进程与线程
  5. lisp将图元追加选择_DNF:哈林防具和海博伦如何选择首饰提升率最大?你选对了吗?...
  6. 使用Metal打造令人惊叹的游戏效果
  7. [SOJ #538]好数 [CC]FAVNUM(2019-8-6考试)
  8. H5网页等链接被微信秒封(拦截、屏蔽、和谐)后最好的解决方法
  9. 简单工厂模式与策略模式
  10. 做新时代的忠诚爱国者写一篇议论文800字
  11. IC面试常考题 Verilog三分频电路设计(占空比50%,三分之一,三分之二)
  12. Python实现生成多个不同半径、互不重叠的圆形的方法
  13. springMVC的大体结构及工作流程
  14. 电脑连接打印机并共享及其他打印机连接
  15. 'net' 不是内部或外部命令,也不是可运行的程序 或批处理文件。'net' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  16. 画论21 刘道醇《五代名画补遗》
  17. border-radius 兼容 IE8浏览器
  18. IBM ServerGuide 9.40
  19. 在python中浮点数怎样转整数_python 浮点数 转 整数python函数每日一讲 - all()
  20. 【JVM高级特性与最佳实践(第3版)-周志明】-学习记录之【自动内存管理】

热门文章

  1. 5.1深入理解计算机系统——系统级I/O
  2. day2:作业 购物车程序及升级版本
  3. python爬虫beautifulsoup4系列4-子节点
  4. Ubuntu中启用关闭Network-manager网络设置问题!
  5. assign,copy,strong,weak,nonatomic的具体理解
  6. 我的第一篇博客,以此写写内心的独白
  7. Linux 内核中的 GCC 特性(zz)
  8. Codeforces Round #470 (rated, Div. 2 C. Producing Snow(思维)
  9. 深入浅出 SpringMVC - 2 提升篇
  10. Scrum项目1.0