题目

给一个\(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的房间的更多相关文章

  1. 【bzoj4031】[HEOI2015]小Z的房间 解题报告

    [bzoj4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含\(n*m\)个格子的格状矩形,每个格子是一个房 ...

  2. 【BZOJ4031】小Z的房间(矩阵树定理)

    [BZOJ4031]小Z的房间(矩阵树定理) 题面 BZOJ 洛谷 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子 ...

  3. 【bzoj4031】[HEOI2015]小Z的房间 Matrix-Tree定理+高斯消元

    [bzoj4031][HEOI2015]小Z的房间 2015年4月30日3,0302 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的 ...

  4. 【bzoj4031】[HEOI2015]小Z的房间 && 【bzoj4894】天赋 (矩阵树定理)

    来两道矩阵树模板: T1:[bzoj4031][HEOI2015]小Z的房间 Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形 ...

  5. 【BZOJ-4031】小z的房间 Matrix-Tree定理 + 高斯消元解行列式

    4031: [HEOI2015]小Z的房间 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 937  Solved: 456[Submit][Statu ...

  6. 【BZOJ4031】【HEOI2015】小Z的房间 [Matrix-Tree][行列式]

    小Z的房间 Time Limit: 10 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 你突然有了一个大房子,房子里面有 ...

  7. bzoj 4031: [HEOI2015]小Z的房间 轮廓线dp

    4031: [HEOI2015]小Z的房间 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 98  Solved: 29[Submit][Status] ...

  8. [HEOI2015]小Z的房间 && [CQOI2018]社交网络

    今天看了一下矩阵树定理,然后学了一下\(O(n ^ 3)\)的方法求行列式. 哦对了,所有的证明我都没看-- 这位大佬讲的好呀: [学习笔记]高斯消元.行列式.Matrix-Tree 矩阵树定理 关于 ...

  9. [BZOJ 4031][LOJ 2122][HEOI 2015] 小Z的房间

    [BZOJ 4031][LOJ 2122][HEOI 2015] 小Z的房间 题意 给定一个 \(n\times m\) 的矩阵, 一些格子是障碍, 相邻的格子(四联通)之间可以连边, 求把非障碍的格 ...

  10. 【刷题】BZOJ 4031 [HEOI2015]小Z的房间

    Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...

随机推荐

  1. 佛山Uber优步司机奖励政策(1月11日~1月17日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  2. 在线tidb+tipd+tikv扩容,迁移,从UC到阿里云

    集群现状: 共有五个节点,配置为16核32g内存,数据节点为1T ssd盘,非数据节点为100g ssd盘: 角色规划: node1 tidb tipd node2 tidb tipd node3 t ...

  3. verilog入门语法学习-第1篇

    1. 如何观察被测模块的响应: 在initial 块中,用系统任务$time 和 $monitor $time 返回当前的仿真时刻 $monitor 只要在其变量列表中有某一个或某几个变 量值发生变化 ...

  4. 【二】H.264/MPEG-4 Part 10 White Paper 翻译之 Prediction of Intra Macroblocks

    翻译版权所有,转载请注明出处~ xzrch@2018.09.14 ------------------------------------------------------------------- ...

  5. 怎么设计好移动APP测试用例

    软件测试工作中我们需要不断的储备和总结自己的知识和经验,怎么设计好移动APP测试用例?如:手机.平板.智能设备,并在特定网络环境下. 我们需要关注的功能点,容易出错的位置,这将对我们整个测试过程起着至 ...

  6. Selenium基础之--01(将浏览器最大化,设置浏览器固定宽、高,操控浏览器前进、后退)

    1,将浏览器最大化 我们知道调用启动的浏览器不是全屏的,这样不会影响脚本的执行,但是有时候会影响我们"观看"脚本的执行. coding=utf-8 from selenium im ...

  7. 前端开发工程师 - 02.JavaScript程序设计 - 第2章.进阶篇

    第2章--进阶篇 类型进阶 类型: Undefined Null Boolean String Number Object 原始类型(值类型):undefined, null, true, " ...

  8. 【swiper】 滑块组件说明

    swiper 滑块视图容器,其原型如下: <swiper indicator-dots="[Boolean]" indicator-color="[Color]&q ...

  9. ajax 个人理解 学习笔记

    W:Ajax Q:异步网络请求.无刷新请求数据. W:ajax的实现流程如下: Q: 创建XHR对象 调用open()方法,创建请求 调用send()方法,发送请求 捕获请求状态,判断请求结果 获取数 ...

  10. 在github上面创建属于自己的个性主页

    圈子里面越来越多的同事在github上面创建自己的项目文档,那里确实高手云集,海内外的技术大牛小牛们都在那儿有一席之地,为“helloword”贡献自己. 以上感慨略过... 这几日正想创建一个自己的 ...