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() ... 
