P4336 [SHOI2016]黑暗前的幻想乡
矩阵树定理(高斯消元+乘法逆元)+容斥
ans=总方案数 -(公司1未参加方案数 ∪ 公司2未参加方案数 ∪ 公司3未参加方案数 ∪ ...... ∪ 公司n未参加方案数)
方案数=生成树方案数 所以用矩阵树定理瞎搞
显然后面的部分可以用容斥原理求解
枚举的时候用一个数转成二进制来表示哪些公司参加/不参加
mod=1e9+7是质数所以可以在高斯消元的时候用逆元搞
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
typedef long long ll;
template <typename T> inline void read(T &x){
char c=getchar(); x=;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=(x<<)+(x<<)+(c^),c=getchar();
}
const int mod=1e9+;
inline ll ksm(ll x,int y){
ll res=;
for(;y;y>>=){
if(y&) res=res*x%mod;
x=x*x%mod;
}return res;
}
struct edge{int x,y;}a[][];
ll f[][];
int n,b[];
inline ll det(){ //高斯消元
ll res=; int c=;
for(int i=;i<n;++i){
int p=i;
for(int j=i+;j<n;++j) if(f[j][i]>f[p][i]) p=j;
if(p!=i) swap(f[i],f[p]),c=-c; //注意行列式每次交换行符号都会改变
for(int j=i+;j<n;++j){
ll div=f[j][i]*ksm(f[i][i],mod-)%mod; //除法转成乘逆元
for(int k=i;k<n;++k) f[j][k]=(f[j][k]-f[i][k]*div%mod+mod)%mod;
}
res=res*f[i][i]%mod;
}return (res*c+mod)%mod;
}
int main(){
read(n); ll ans=;
for(int i=;i<n;++i){
read(b[i]);
for(int j=;j<=b[i];++j) read(a[i][j].x),read(a[i][j].y);
}
for(int i=;i<=(<<(n-))-;++i){ //i转为二进制数表示方案:0/1 表示是否参加
memset(f,,sizeof(f)); //清空重建图
int p=i,cnt=;
for(int j=;p;++j,p>>=){
if(!(p&)) continue; //二进制表示下该位为0->没参加该方案
for(int k=;k<=b[j];++k){ //kirchhoff矩阵=度数矩阵-邻接矩阵
int X=a[j][k].x,Y=a[j][k].y;
++f[X][X]; ++f[Y][Y];
f[X][Y]=(f[X][Y]-+mod)%mod; //注意减法要重新取模
f[Y][X]=(f[Y][X]-+mod)%mod;
}++cnt;
}
ans=(ans+((n--cnt)& ? -det():det())+mod)%mod; //容斥原理决定是加还是减
}printf("%lld",ans);
return ;
}
P4336 [SHOI2016]黑暗前的幻想乡的更多相关文章
- 题解 P4336 [SHOI2016]黑暗前的幻想乡
题解 前置芝士 :矩阵树定理 本题是一道计数题,有两个要求: 建造的公路构成一颗生成树 每条公路由不同的公司建造,每条公路与一个公司一一映射 那么看到这两个要求后,我们很容易想到第一个条件用矩阵树定理 ...
- 洛谷P4336 [SHOI2016]黑暗前的幻想乡 [Matrix-Tree定理,容斥]
传送门 思路 首先看到生成树计数,想到Matrix-Tree定理. 然而,这题显然是不能Matrix-Tree定理硬上的,因为还有每个公司只能建一条路的限制.这个限制比较恶心,尝试去除它. 怎么除掉它 ...
- Luogu P4336 [SHOI2016]黑暗前的幻想乡 矩阵树定理+容斥原理
真是菜到爆炸....容斥写反(反正第一次写qwq) 题意:$n-1$个公司,每个公司可以连一些边,求每个边让不同公司连的生成树方案数. 矩阵树定理+容斥原理(注意到$n$不是很大) 枚举公司参与与否的 ...
- bzoj 4596 [Shoi2016]黑暗前的幻想乡 矩阵树定理+容斥
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 559 Solved: 325[Submit][Sta ...
- bzoj4596[Shoi2016]黑暗前的幻想乡 Matrix定理+容斥原理
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 464 Solved: 264[Submit][Sta ...
- [ZJOI2016]小星星&[SHOI2016]黑暗前的幻想乡(容斥)
这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. ...
- 【BZOJ 4596】 4596: [Shoi2016]黑暗前的幻想乡 (容斥原理+矩阵树定理)
4596: [Shoi2016]黑暗前的幻想乡 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 324 Solved: 187 Description ...
- 【BZOJ4596】[Shoi2016]黑暗前的幻想乡 容斥+矩阵树定理
[BZOJ4596][Shoi2016]黑暗前的幻想乡 Description 幽香上台以后,第一项措施就是要修建幻想乡的公路.幻想乡有 N 个城市,之间原来没有任何路.幽香向选民承诺要减税,所以她打 ...
- bzoj4596/luoguP4336 [SHOI2016]黑暗前的幻想乡(矩阵树定理,容斥)
bzoj4596/luoguP4336 [SHOI2016]黑暗前的幻想乡(矩阵树定理,容斥) bzoj Luogu 题解时间 看一看数据范围,求生成树个数毫无疑问直接上矩阵树定理. 但是要求每条边都 ...
随机推荐
- CodeForces 832B Petya and Exam
B. Petya and Exam time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 使用Pangolon在同一副图中,画出两个轨迹,比较误差
使用 code/ground-truth.txt 和 code/estimate.txt 两条轨迹.请你根据上面公式,实现 RMSE的计算代码,给出最后的 RMSE 结果.作为验算,参考答案为:2.2 ...
- iOS多线程编程之线程间的通信(转载)
一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 ...
- 小希的迷宫---hdu1272
http://acm.hdu.edu.cn/showproblem.php?pid=1272 #include<stdio.h> #include<string.h> #inc ...
- Socket通信的Python实现
Python中实现socket通信,socket通信的服务端比较复杂,而客户端非常简单,所以客户端基本上都是用sockct模块实现,而服务 端用有很多模块可以使用.下面就说一下服务端可使用的模块. 模 ...
- mysql 数据操作 多表查询 子查询 虚拟表介绍
子查询 把一个sql语句放在括号里 ,这个括号里sql语句查询结果其实就是一张表,并且是一个临时在内存里存在的虚拟表 可以用括号把一个查询sql语句括起来 得到查询的结果并且用as 为这张虚拟表起个别 ...
- python 基础 列表生成式 生成器
列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式 举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, ...
- Unity 补充安装
当需要下载 安装Unity之时没勾选的一些组件时, 1.去Unity官网点开Unity旧版本 2.找到你的Unity版本,然后只要下载Unity安装程序 3.点开安装程序,去掉已安装组件的勾选,勾选你 ...
- 20170809直接访问功能测试Postman
20170809直接访问功能测试Postman 1 打开admin账户登录界面,打开F12,登录 admin账户,点击系统管理,用户设置,获得网址http://10.200.44.69:8080/cl ...
- poj2524(简单并查集)
#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>u ...