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个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...
随机推荐
- vue核心概念
# 1. vuex是什么 github站点: https://github.com/vuejs/vuex 在线文档: https://vuex.vuejs.org/zh-cn/ 简单来说: 对应用中组 ...
- Java设计模式(17)——行为模式之观察者模式(Observer)
一.概述 概念 UML简图 我们根据一个示例得类图来分析角色 角色 抽象主题:保存观察者聚集(集合),管理(增删)观察者 抽象观察者:定义具体观察者的抽象接口,在得到主题通知后更新自己 具体主题:将有 ...
- 使用PowerDesign15反向生成数据库
在Pd15中建立物理模型后,可以通过反向工程直接生成数据库的表结构.主要有以下几个步骤: 1. 首先设置一下数据库配置,选择对应要使用的数据库(此处选择Sql Server 2008 R ...
- MySql 增加字段 删除字段 修改字段名称 修改字段类型
//1.增加一个字段 alter table user add COLUMN new1 VARCHAR(20) DEFAULT NULL; //增加一个字段,默认为空 alter table user ...
- Qt-QML-Popup,弹层界面编写
随着接触Qt的时间的增加,也逐渐的发现了Qt 的一些不人信话的一些地方,不由的想起一句话,也不知道是在哪里看到的了“一切变成语言都是垃圾,就C++还可以凑合用”大致意思是这样.最近项目的祝界面框架都基 ...
- 375. Clone Binary Tree【LintCode java】
Description For the given binary tree, return a deep copy of it. Example Given a binary tree: 1 / \ ...
- java基础-Comparator接口与Collections实现排序算法
java 排序Comparable和Comparator使用 java提供了两个排序用的接口Comparable和Comparator,一般情况下使用区别如下: Comparable 接口用于类的固定 ...
- (原创)白话KMP算法详解
引子:BF暴力算法 KMP算法知名度相当高,燃鹅其理解难度以及代码实现对于初学数据结构和算法的同学并不友好,经过两天的总结,详细总结KMP算法如下: 初学串的模式匹配时,我们都会接触到,或者说应该能想 ...
- python常用命令—查看模块所在位置
环境:ipython3 交互式解释器 语法: import 模块名 模块名.__file__ 功能: 查看模块的所在位置 例:
- 机器学习-线性回归LinearRegression
概述 今天要说一下机器学习中大多数书籍第一个讲的(有的可能是KNN)模型-线性回归.说起线性回归,首先要介绍一下机器学习中的两个常见的问题:回归任务和分类任务.那什么是回归任务和分类任务呢?简单的来说 ...