●BZOJ 4596 [Shoi2016]黑暗前的幻想乡
题链:
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==c
R=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;
}
●BZOJ 4596 [Shoi2016]黑暗前的幻想乡的更多相关文章
- bzoj 4596 [Shoi2016]黑暗前的幻想乡 矩阵树定理+容斥
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 559 Solved: 325[Submit][Sta ...
- BZOJ 4596: [Shoi2016]黑暗前的幻想乡
Sol 容斥原理+Matrix-Tree定理.容斥跟小星星那道题是一样的,然后...直接Matrix-Tree定理就可以了... 复杂度\(O(2^{n-1}n^3)\) PS:调了好久啊QAQ 明明 ...
- bzoj 4596: [Shoi2016]黑暗前的幻想乡【容斥原理+矩阵树定理】
真是简单粗暴 把矩阵树定理的运算当成黑箱好了反正我不会 这样我们就可以在O(n^3)的时间内算出一个无向图的生成树个数了 然后题目要求每个工程队选一条路,这里可以考虑容斥原理:全选的方案数-不选工程队 ...
- BZOJ 4596: [Shoi2016]黑暗前的幻想乡(容斥+Matrix_Tree)
传送门 解题思路 看到计数想容斥--\(from\) \(shadowice1984\)大爷.首先求出原图的生成树个数比较容易,直接上矩阵树定理,但这样会多算一点东西,会把\(n-2\)个公司的多算进 ...
- 【BZOJ 4596】 4596: [Shoi2016]黑暗前的幻想乡 (容斥原理+矩阵树定理)
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 324 Solved: 187 Description ...
- 【BZOJ】4596: [Shoi2016]黑暗前的幻想乡
[题意]给定n个点的无向完全图,有n-1个公司各自分管一部分路,要求所有公司都有修路的生成树数.n<=17. [算法]容斥原理+生成树计数(矩阵树定理) [题解]每个生成树方案是一个公司有无修路 ...
- bzoj4596[Shoi2016]黑暗前的幻想乡 Matrix定理+容斥原理
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 464 Solved: 264[Submit][Sta ...
- bzoj4596/luoguP4336 [SHOI2016]黑暗前的幻想乡(矩阵树定理,容斥)
bzoj4596/luoguP4336 [SHOI2016]黑暗前的幻想乡(矩阵树定理,容斥) bzoj Luogu 题解时间 看一看数据范围,求生成树个数毫无疑问直接上矩阵树定理. 但是要求每条边都 ...
- [ZJOI2016]小星星&[SHOI2016]黑暗前的幻想乡(容斥)
这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. ...
随机推荐
- Beta第一天
听说
- 每日冲刺报告——Day3(Java-Team)
第三天报告(11.4 周六) 团队:Java-Team 成员: 章辉宇(284) 吴政楠(286) 陈阳(PM:288) 韩华颂(142) 胡志权(143) github地址:https://git ...
- 2017-2018-1 1623 bug终结者 冲刺002
bug终结者 冲刺002 by 20162329 张旭升 今日冲刺任务: 能够显示主菜单和功能 游戏需要提供主菜单让玩家进行游戏设置,同时能能够把地图文件中的信息转换成为图像显示到游戏界面上 能够实现 ...
- electron-vue工程创建
没有vue创建经验请移步至 vue下载与安装 使用vue创建electron-vue工程 vue init simulatedgreg/electron-vue my-project 安装elemen ...
- 学号:201621123032 《Java程序设计》第1周学习总结
1:本周学习总结 JDK,JRE,JVM三者的含义和关系.JDK是java开发工具包,包含了java的运行环境,java工具和类文库.例如java.javac.jar....可以把 .java编译成. ...
- python 面向对象设计思想发展史
这篇主要说的是程序设计思想发展历史,分为概述和详细发展历史 一,概述 1940年以前:面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的 指令和数 据.简单来 ...
- 第二篇:利用shell脚本执行webservice请求——基于soap
1. 项目背景 以往我们在开发基于webservice的项目中,我们总习惯于直接使用webservice的一些框架,如Axis,axis2和Xfire等.框架的好处是将webservice所涉及到的s ...
- DBA 小记 — 分库分表、主从、读写分离
前言 我在上篇博客 "Spring Boot 的实践与思考" 中比对不同规范的 ORM 框架应用场景的时候提到过主从与读写分离,本篇随笔将针对此和分库分表进行更深入地探讨. 1. ...
- python之路--day13-模块
1,什么是模块 模块就是系统功能的集合体,在python中,一个py文件就是一个模块, 例如:module.py 其中module叫做模块名 2,使用模块 2.1 import导入模块 首次带入模块发 ...
- vue.js+socket.io+express+mongodb打造在线聊天
vue.js+socket.io+express+mongodb打造在线聊天 在线地址观看 http://www.chenleiming.com github地址 https://github.com ...