题目

给一个\(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. Django中ORM简述

    ORM:对象关系映射(Object Relational Mapping,简称ORM) 作用:根据类生成表结构,将对象.列表的操作转换成对象的SQL语句,将SQL语句查询的结果转换为对象或列表 优点: ...

  2. Linux学习-rsyslog.service :记录登录文件的服务

    rsyslog.service 的配置文件:/etc/rsyslog.conf 我们现在知道 rsyslogd 可以负责主机产生的各个信息的登录,而这些信息本身是有『严重等级』之分的, 而且, 这些资 ...

  3. 成都Uber优步司机奖励政策(2月17日)

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

  4. Java语言简介

    Java即计算机编程语言 1.概念 Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Jav ...

  5. python之Queue

    一.多进程的消息队列 “消息队列”是在消息的传输过程中保存消息的容器 消息队列最经典的用法就是消费者和生成者之间通过消息管道来传递消息,消费者和生成者是不通的进程.生产者往管道中写消息,消费者从管道中 ...

  6. nodejs 事件机制

    node 事件机制   一 三种定时器 NodeJS中有三种类型的定时器:超时时间.时间间隔.即时定时器 1.超时时间:setTimeout(callback,delayMilliSeconds,[a ...

  7. RF上传图片各种失败坑,使用pywin32来操作windows窗体

    这个上传按钮,使用 Choose File,失败不知道为什么... Name:Choose FileSource:Selenium2Library <test library>Argume ...

  8. JMeter 录制APP脚本

    具体步骤: 1.启动JMeter: 2.在“测试计划”中添加“线程组”: 3.“工作台”中添加“HTTP代理服务器”: 4.配置代理服务器:端口:8888(默认值),HTTPS Domains:192 ...

  9. centos下testlink的部署(基于xampp)

    1. sudu -i 切换root用户      cd /opt切换到opt目录下(在linux下默认的下载文件目录在opt下) 执行命令下载xampp:      https://sourcefor ...

  10. jmeter 函数助手

    1.选项,函数助手对话框,打开函数助手 2.使用方法 输入参数,点击生成,可以直接使用(Name of variable in which to store the result (optional) ...