bzoj4031-小Z的房间
题目
给一个\(n\*m\)的矩阵,每个点可能为“.”或“*”,有多少种方法把矩阵中的点全部连接起来,并且每两个点之间只有一条路径。
分析
题目所求的是一个矩阵内的生成树计数。很容易把这个矩阵转化为一个图。现在我们要在这个图上求生成树计数。
这里要用到Matrix-Tree定理。
这个定理的证明十分复杂,但是描述很简单。
假设有\(n\)个点,我们的矩阵\(A\)的定义为 :
- 如果两个点\(i\)和\(j\)有直接连边,那么\(A_{ij}\)为1,否则为0
- \(A_{ii}\)为点\(i\)的度数
这个矩阵的任意一个\(n-1\)阶主子式(即去掉任意的第\(i\)行和第\(i\)列)的行列式就是生成树的方案数。
在实现时,我们选择最后一行和最后一列去掉,计算剩下的行列式。当然去掉第2行和第2列,第3行和第3列,答案也是一样的。
我们称矩阵\(A\)为kirchhoff矩阵。
这个矩阵有几个特殊性质,也符合计数: - kirchhoff矩阵的行列式为0,因为每行的和都为0
- 若图不连通,kirchhoff矩阵的任意n-1阶主子式的行列式为0
- 若图为一棵树,kirchhoff矩阵的任意n-1阶主子式的行列式为1
时间复杂度为:\(O(n^3*logn)\)
代码
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long giant;
const int maxn=10;
const giant q=1e9;
const int maxm=maxn*maxn;
const int xx[]={-1,0,1,0};
const int yy[]={0,1,0,-1};
char s[maxn][maxn];
giant a[maxm][maxm];
void sw(giant a[],giant b[],int n) {
for (int i=1;i<=n;++i) swap(a[i],b[i]);
}
int el(giant a[],giant b[],int t,int n) {
int tf=1;
if (a[t]>b[t]) sw(a,b,n),tf*=-1;
while (a[t] && b[t]) {
giant k=b[t]/a[t];
for (int i=1;i<=n;++i) (b[i]=b[i]-(a[i]*k)%q+q)%=q;
if (a[t]>b[t]) sw(a,b,n),tf*=-1;
}
if (!a[t]) sw(a,b,n),tf*=-1;
return tf;
}
giant eliminate(int n) {
int f=1;
for (int i=1;i<n;++i) {
if (a[i][i]==0) {
for (int j=i+1;j<=n;++j) if (a[j][i]) {
f*=-1;
sw(a[i],a[j],n);
break;
}
}
for (int j=i+1;j<=n;++j) f*=el(a[i],a[j],i,n);
}
giant ret=1;
for (int i=1;i<=n;++i) ret=(ret*a[i][i]+q)%q;
return (ret*f+q)%q;
}
int bh[maxn][maxn];
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
int n,m;
scanf("%d%d",&n,&m);
int dx=0;
for (int i=1;i<=n;++i) scanf("%s",s[i]+1);
for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) if (s[i][j]=='.') bh[i][j]=++dx;
for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) if (s[i][j]=='.') {
int idn=bh[i][j];
for (int k=0;k<4;++k) {
int x=i+xx[k],y=j+yy[k];
if (x<1 || y<1 || x>n || y>m || s[x][y]!='.') continue;
int id=bh[x][y];
a[idn][id]=-1;
a[idn][idn]++;
}
}
giant ans=eliminate(dx-1);
printf("%lld\n",ans);
}
bzoj4031-小Z的房间的更多相关文章
- 【bzoj4031】[HEOI2015]小Z的房间 解题报告
[bzoj4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含\(n*m\)个格子的格状矩形,每个格子是一个房 ...
- 【BZOJ4031】小Z的房间(矩阵树定理)
[BZOJ4031]小Z的房间(矩阵树定理) 题面 BZOJ 洛谷 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子 ...
- 【bzoj4031】[HEOI2015]小Z的房间 Matrix-Tree定理+高斯消元
[bzoj4031][HEOI2015]小Z的房间 2015年4月30日3,0302 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的 ...
- 【bzoj4031】[HEOI2015]小Z的房间 && 【bzoj4894】天赋 (矩阵树定理)
来两道矩阵树模板: T1:[bzoj4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形 ...
- 【BZOJ-4031】小z的房间 Matrix-Tree定理 + 高斯消元解行列式
4031: [HEOI2015]小Z的房间 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 937 Solved: 456[Submit][Statu ...
- 【BZOJ4031】【HEOI2015】小Z的房间 [Matrix-Tree][行列式]
小Z的房间 Time Limit: 10 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 你突然有了一个大房子,房子里面有 ...
- bzoj 4031: [HEOI2015]小Z的房间 轮廓线dp
4031: [HEOI2015]小Z的房间 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 98 Solved: 29[Submit][Status] ...
- [HEOI2015]小Z的房间 && [CQOI2018]社交网络
今天看了一下矩阵树定理,然后学了一下\(O(n ^ 3)\)的方法求行列式. 哦对了,所有的证明我都没看-- 这位大佬讲的好呀: [学习笔记]高斯消元.行列式.Matrix-Tree 矩阵树定理 关于 ...
- [BZOJ 4031][LOJ 2122][HEOI 2015] 小Z的房间
[BZOJ 4031][LOJ 2122][HEOI 2015] 小Z的房间 题意 给定一个 \(n\times m\) 的矩阵, 一些格子是障碍, 相邻的格子(四联通)之间可以连边, 求把非障碍的格 ...
- 【刷题】BZOJ 4031 [HEOI2015]小Z的房间
Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...
随机推荐
- javascript array.property.slice.call
function foo() { //var var1=Array.prototype.slice.call(arguments); var var1=[].slice.call(arguments) ...
- 北京Uber司机7月13日奖励政策更新
各位司机朋友: 从7月13日(周一)起,奖励政策将进行调整,具体如下: 滴滴快车单单2.5倍,注册地址:http://www.udache.com/如何注册Uber司机(全国版最新最详细注册流程)/月 ...
- DSP5509的RTC实验-第3篇
1. RTC实时时钟,不在过多介绍,本例程直接调用芯片支持库CSL的库函数,用起来比较简单 main() { CSL_init(); printf ("\nTESTING...\n" ...
- Fat Jar - Myeclipse插件安装使用方法- 完美解决
Eclipse可以安装一个叫Fat Jar的插件,用这个插件打包非常方便,Fat Jar的功能非常强大. 工具/原料 Eclipse Kepler Fat Jar 方法/步骤 1 Fat Jar功能非 ...
- PHP MySQL 安全方案
1 转义与清除转义 // 对 用户提交的数据 ' " \ 进行转义 if ( get_magic_quotes_gpc() ) { function del_magic_quotes($v ...
- golang 仿python pack/unpack
写得不完善也不完美 尤其是高低位转换那(go和c 二进制高地位相反 需要转换,还有go int转[]byte长度是4位),希望牛人看后指导一下 项目需要通过socket调取 客户端是go ,服务器端是 ...
- FCL中你不得不知的几种委托
FCL中丰富的类库信息极大的方便了我们的编码,很多我们日常经常用到的类型,FCL中已经帮我们定义好,下面要介绍的就是FCL中定义好的几种委托类型,直接使用它们不仅能提高我们的编码效率,而且还能让我们的 ...
- unittest,selenium——批量,多线程执行多文档用例
之前做过批量执行多.py文件,为了省时也做过单py文件多线程,现在做多py文件用例多线程 # coding:utf-8import unittestimport osimport timeimport ...
- (C#)设计模式之装饰模式
1.装饰模式 动态的给一个对象添加一些额外的职责,就添加功能来说,装饰模式比生成子类更加灵活.*装饰模式是为已有功能动态添加更多功能的一种方式.*装饰模式将原有类中的核心职责与装饰功能分离.简化了原有 ...
- 校招小白机考入坑之从键盘输入java的各种数据类型
//1.从键盘输入一个整型(其他基本类型类似) Scanner sc =new Scanner(System.in); sc.hasNextInt(); int str1 = sc.nextInt() ...