原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4031

Description

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

你想要打通一些相邻房间的墙,使得所有房间能够互相到达。在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙)。同时,你不希望在房子中有小偷的时候会很难抓,所以你希望任意两个房间之间都只有一条通路。现在,你希望统计一共有多少种可行的方案。

Input

第一行两个数分别表示n和m。

接下来n行,每行m个字符,每个字符都会是’.’或者’*’,其中’.’代表房间,’*’代表柱子。

Output

一行一个整数,表示合法的方案数 Mod 10^9

Sample Input

3 3
...
...
.*.

Sample Output

15

HINT

对于前100%的数据,n,m<=9

题意概述:
  给出一个矩阵,由N*M个格子组成,这个矩阵中有'*'和'.'。可以把矩阵中方格的一些边破坏掉,但是不可以破坏这个矩阵的边缘和与'*'相邻的边。现在询问由多少种方案让所有的'.'连通并且任意两个'.'之间只有唯一一条路径。换言之要求求这个矩阵在规则下可以形成的生成树的数量。答案mod10^9。
  N,M<=9.

分析:
  实际上当你了解了矩阵树定理了之后这TM就是一个裸题......
  只是取mod的时候有一点魔性啊......mmj我在脑补些什么毛病又来了!!!!具体的操作方法是辗转相除,利用辗转相除的原理弄掉第i项系数。根据行列式的性质,可以发现相除只会改变行列式的正负情况(因为有交换两行的操作),而并不会改变行列式的绝对值。因此我们只需要维护行列式的值的符号位就可以了。
  注意一下给新图编号的时候要注意不要给'*'编号,不然这个编号不连续图就......不连通了......你就得到了一个0分的优秀算法!!!(除非这个图本来不连通你可以有个10分之类的)
  时间复杂度O((N*M)^3)(因为辗转相除的原因带上常数log)。

getting新姿势—行列式

定义:

  一个方阵的行列式的形式化定义为Sigma{ (-1)^t*a1p1*a2p2*...*anpn | p1,p2,...,pn为1~n的全排列,t表示这个排列中的逆序对数 },也就是说行列式实际上是一个标量。

性质:

  1.首先定义一个矩阵A,记这个矩阵的转置为AT(把矩阵中元素ai,j变到aj,i),记方阵A的行列式为|A|,那么有|A|=|AT|。

  证明:首先看到定义式中a的下标,可以发现二元组下标(1,p1),(2,p2),...,(n,pn),将其按照第二维p排序之后,每消失一个关于第二维的逆序对就会出现一个关于第一维的逆序对,因此Sigma集中的每一种情况放到转置矩阵之中a的乘积没有变,而逆序对数也没有变,得证。

  2.如果将A中的两行互换得到A',那么有|A|=-|A'|。

  证明:首先,操作之后可以发现最后产生的效果实际上就是在Sigma集中交换了两个元素的位置,即对于原Sigma集中的每一个状态一定能够在新的Sigma集中找到唯一对应的一个状态使得Sigma集中所有元素的值没有变,但是只有两个元素的下标发生了交换。而在一个序列中交换两个元素的位置一定会让逆序对数的奇偶性发生变化(易证,懒得写了ORZ),因此前后对应状态对Sigma集产生的贡献抵消,最终加起来的结果为0.

  3.把A的一行所有元素全部乘以k,行列式的值也要乘以k。

  证明:考虑定义式,很容易发现这个性质。

  4.两个矩阵只有一行不同,那么他们的行列式之和等于两个矩阵不同的那一行相加之后得到的矩阵的行列式。

  证明:考虑一下乘法分配律,结合定义式,易证。

  5.将矩阵的某一行中的所有元素对应加上另外一行乘以某个数之后的所有元素,得到的矩阵行列式等于原矩阵的行列式。

  证明:首先可以把新的矩阵拆开。对于一个矩阵中的两行,如果有一行是另一行的倍数,那么这个矩阵的行列式为0。把常数踢出去,考虑Sigma集中的一种情况,可以找到另外一种情况使得Sigma集中的所有元素值都不变但是某两个值的下标交换,这两个值对应的来源就是两个有倍数关系的行,交换下标之后逆序对数奇偶性变化,贡献抵消,最终行列式值为0。得证。
  6.一个上三角矩阵的行列式的值就是这个矩阵主对角线上的所有值的乘积。

  证明:很容易发现这种情况下只有p1,p2,...,pn分别为1,2,...,n的时候才有贡献。

  利用以上6个性质得到的结论,尤其是第5,6个,可以使用高斯消元的方法把整个矩阵消成一个上三角矩阵,这个上三角矩阵主对角线上的所有数相乘就是这个矩阵行列式的值。

应用:

基尔霍夫矩阵!

  对于一个无向连通图,构造一个度数矩阵A(实际上是一个方阵),当i=i的时候a[i][i]=du[i],否则为0。再构造一个邻接矩阵G,令这张图的基尔霍夫矩阵为C=A-G,那么这张图的生成树数量就是基尔霍夫矩阵任意余子式Mi,i绝对值(余子式Mi,i指的是将矩阵中的第i行i列的元素去掉之后得到的矩阵的行列式)。

  emmmmmm......其他的之后来填坑。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int maxn=;
const int maxm=;
const int mo=;
typedef long long LL; int N,M,tot;
char mp[maxn][maxn];
int A[maxm][maxm],C[maxm][maxm],G[maxm][maxm],id[maxn][maxn]; void data_in()
{
scanf("%d%d",&N,&M);
for(int i=;i<=N;i++) scanf("%s",mp[i]+);
}
int Gauss(int a[maxm][maxm])
{
int flag=;
for(int i=;i<tot;i++){
int tmp=i;
for(int j=i+;j<tot;j++)
if(a[j][i]){ tmp=j; break; }
for(int k=i;k<tot;k++) swap(a[i][k],a[tmp][k]);
if(tmp!=i) flag=-flag;
for(int j=i+;j<tot;j++){
while(a[j][i]){
int t=a[j][i]/a[i][i];
for(int k=i;k<tot;k++) a[j][k]=(a[j][k]-1ll*t*a[i][k]%mo+mo)%mo;
if(!a[j][i]) break;
flag=-flag;
for(int k=i;k<tot;k++) swap(a[j][k],a[i][k]);
}
}
}
for(int i=;i<tot;i++) flag=(1ll*flag*a[i][i])%mo;
return (flag+mo)%mo;
}
void work()
{
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
if(mp[i][j]!='*') id[i][j]=++tot;
for(int i=;i<=N;i++)
for(int j=;j<=M;j++){
if(i-&&mp[i-][j]!='*') C[id[i][j]][id[i-][j]]=,A[id[i][j]][id[i][j]]++;
if(j-&&mp[i][j-]!='*') C[id[i][j]][id[i][j-]]=,A[id[i][j]][id[i][j]]++;
if(i+<=N&&mp[i+][j]!='*') C[id[i][j]][id[i+][j]]=,A[id[i][j]][id[i][j]]++;
if(j+<=M&&mp[i][j+]!='*') C[id[i][j]][id[i][j+]]=,A[id[i][j]][id[i][j]]++;
}
for(int i=;i<=tot;i++)
for(int j=;j<=tot;j++)
G[i][j]=A[i][j]-C[i][j];
printf("%d\n",Gauss(G));
}
int main()
{
data_in();
work();
return ;
}

BZOJ 4031 HEOI2015 小Z的房间 基尔霍夫矩阵+行列式+高斯消元 (附带行列式小结)的更多相关文章

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

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

  2. BZOJ 4031: [HEOI2015]小Z的房间 高斯消元 MartixTree定理 辗转相除法

    4031: [HEOI2015]小Z的房间 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4031 Description 你突然有了一个 ...

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

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

  4. BZOJ 4031 [HEOI2015]小Z的房间(Matrix-Tree定理)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4031 [题目大意] 你突然有了一个大房子,房子里面有一些房间. 事实上,你的房子可以看 ...

  5. BZOJ 4031: [HEOI2015]小Z的房间(Matrix Tree)

    传送门 解题思路 矩阵树定理模板题.矩阵树定理是求图中最小生成树个数,做法是首先求出基尔霍夫矩阵,就是度数矩阵\(-\)邻接矩阵.然后再求出这个矩阵的行列式,行列式的求法就是任意去掉一行一列,然后高斯 ...

  6. BZOJ:4031: [HEOI2015]小Z的房间

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1103  Solved: 536[Submit][Status][Discuss] Descripti ...

  7. BZOJ.4031.[HEOI2015]小Z的房间(Matrix Tree定理 辗转相除)

    题目链接 辗转相除解行列式的具体实现? 行列式的基本性质. //864kb 64ms //裸的Matrix Tree定理.练习一下用辗转相除解行列式.(因为模数不是质数,所以不能直接乘逆元来高斯消元. ...

  8. BZOJ 4031: [HEOI2015]小Z的房间 [矩阵树定理 行列式取模]

    http://www.lydsy.com/JudgeOnline/problem.php?id=4031 裸题........ 问题在于模数是$10^9$ 我们发现消元的目的是让一个地方为0 辗转相除 ...

  9. BZOJ 4031: [HEOI2015]小Z的房间 Matrix-Tree定理

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4031 题解: Matrix-tree定理解决生成树计数问题,其中用到高斯消元法求上三角矩 ...

随机推荐

  1. [UNIX]UNIX常用命令总结

    (1)查看服务器IP信息 $netstat -in (2)查看挂载磁盘信息 #sam #需要在root账号下查看

  2. ios应用数据存储方式(偏好设置)-转

    一.简单介绍 1.很多ios应用都支持偏好设置,比如保存用户名,密码,字体大小等设置,ios提供了一套标准的解决方案来为应用加入偏好设置功能. 2.每个应用都有个NSUserDefaults实例,通过 ...

  3. 开发一个c#的数据库连接池

    c#操作数据库是一个经典,用习惯了以后真感觉不错,很简单的.现在很多关系数据库都支持c#.c#的ADO.NET规范都遵守. 对于一般的设置,ADO.NET都放在数据库连接字符串上.比如池化,连接超时等 ...

  4. php第三节(运算符)

    <?php //算术运算符 + - * / % //++ 前加加 先做加运算后座赋值运算 后加加 先做赋值运算后座加运算 //-- 前减减 先做加运算后座赋值运算 后减减 先做赋值运算后座加运算 ...

  5. 【TOJ 3369】CD(二分)

    描述 Jack and Jill have decided to sell some of their Compact Discs, while they still have some value. ...

  6. Python3集成安装xadmin

    Python3集成安装xadmin1:创建虚拟环境C:\Users\Adminstrator>mkvirtualenv -p C:\Python34\python.exe MyDjango如果提 ...

  7. haystack+Elasticsearch搜素引擎

    搜索引擎原理 通过搜索引擎进行数据查询时,搜索引擎并不是直接在数据库中进行查询,而是搜索引擎会对数据库中的数据进行一遍预处理,单独建立起一份索引结构数据. 我们可以将索引结构数据想象成是字典书籍的索引 ...

  8. 关于api接口

    前阵子一直疯狂的找关于php的api接口方面的资料来学习,总结了一下,无非就是请求数据,然后返回数据,当然也要设置相关安全措施,比如认证口令 等.返回数据格式是json 还是xml 看自己需求咯

  9. Hadoop(4)--Hbase

    Hadoop 其它组成角色介绍--Hbase 在apache的官方网站上,对于Hbase的定义是他是Hadoop的第一个分布式.可扩展的大数据存储的数据库,他的目标是将非常大的表托管到一个集群中进行相 ...

  10. Hadoop(2)--hdfs

    Hadoop(2) Hadoop底层封装的的是HDFS和MapReduce两种框架 在Hdfs中采用的是主从结构(Madter-slaver)就像领导和员工一样,领导负责整个公司的管理工作,而员工就负 ...