来两道矩阵树模板:

T1:【bzoj4031】[HEOI2015]小Z的房间

Description

你突然有了一个大房子,房子里面有一些房间。事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子。在一开始的时候,相邻的格子之间都有墙隔着。
你想要打通一些相邻房间的墙,使得所有房间能够互相到达。在此过程中,你不能把房子给打穿,或者打通柱子(以及柱子旁边的墙)。同时,你不希望在房子中有小偷的时候会很难抓,所以你希望任意两个房间之间都只有一条通路。现在,你希望统计一共有多少种可行的方案。

Input

第一行两个数分别表示n和m。
接下来n行,每行m个字符,每个字符都会是’.’或者’*’,其中’.’代表房间,’*’代表柱子。

Output

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

题解:

  这是一道典型的矩阵树裸题……

  不过,这取模 10^9 不是质数,不能普通的高斯消元,要使用辗转相除法。

 int f=;
for(int i=;i<cnt;i++){
for(int j=i+;j<=cnt;j++){
while(a[j][i]){
int t=a[j][i]/a[i][i];
for(int k=i;k<=cnt;k++)
a[j][k]=(a[j][k]-1LL*a[i][k]*t%mod+mod)%mod;
if(a[j][i]==)break;
for(int k=i;k<=cnt;k++)swap(a[i][k],a[j][k]);
f=-f;
}
}
}

  这里涉及到交换,貌似统计答案要变为相反数……

COMPLETE CODE:

 #include<cstdio>
#include<algorithm>
using namespace std; #define mod 1000000000
int n,m,cnt,ans=,a[][],id[][];
char s[]; int qpow(int x,int y){
int ans=;
while(y){
if(y&)ans=1LL*ans*x%mod;
y>>=,x=1LL*x*x%mod;
}
return ans;
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=m;j++){
if(s[j]=='*')continue;
id[i][j]=++cnt;
if(id[i-][j]){
a[id[i-][j]][id[i][j]]--;
a[id[i][j]][id[i-][j]]--;
a[id[i][j]][id[i][j]]++;
a[id[i-][j]][id[i-][j]]++;
}if(id[i][j-]){
a[id[i][j-]][id[i][j]]--;
a[id[i][j]][id[i][j-]]--;
a[id[i][j]][id[i][j]]++;
a[id[i][j-]][id[i][j-]]++;
}
}
}
cnt--;
for(int i=;i<=cnt;i++)
for(int j=;j<=cnt;j++)
if(a[i][j]<)a[i][j]+=mod;
int f=;
for(int i=;i<cnt;i++){
for(int j=i+;j<=cnt;j++){
while(a[j][i]){
int t=a[j][i]/a[i][i];
for(int k=i;k<=cnt;k++)
a[j][k]=(a[j][k]-1LL*a[i][k]*t%mod+mod)%mod;
if(a[j][i]==)break;
for(int k=i;k<=cnt;k++)swap(a[i][k],a[j][k]);
f=-f;
}
}
}
for(int i=;i<=cnt;i++)
ans=1LL*ans*a[i][i]%mod;
printf("%d",~f?ans:(mod-ans)%mod);
}

T2:【bzoj4894】天赋

Description

小明有许多潜在的天赋,他希望学习这些天赋来变得更强。正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的。也就是说,有一些天赋必须是要在学习了另一个天赋的条件下才能学习的。比如,要想学会"开炮",必须先学会"开枪"。一项天赋可能有多个前置天赋,但只需习得其中一个就可以学习这一项天赋。上帝不想为难小明,于是小明天生就已经习得了1号天赋-----"打架"。于是小明想知道学习完这n种天赋的方案数,答案对1,000,000,007取模。(两种方案不同指的是存在某种天赋的前置天赋不同)

Input

第一行一个整数n。
接下来是一个n*n的01矩阵,第i行第j列为1表示习得天赋j的一个前置天赋为i。
数据保证第一列和主对角线全为0。
n<=300

Output

第一行一个整数,问题所求的方案数。

题解:

  这是一道有向图生成树计数的裸题……

  没什么好说的。

CODE:

 #include<iostream>
#include<cstdio>
using namespace std; #define mod 1000000007
char s[];
int n,a[][],ans=; int qpow(int x,int y){
int ans=;
while(y){
if(y&)ans=1LL*ans*x%mod;
y>>=,x=1LL*x*x%mod;
}
return ans;
} void Gauss(){
for(int i=;i<n;i++){
for(int j=i+;j<=n;j++){
if(a[j][i]==)continue;
if(a[i][i]==){
putchar('');
exit();
}
int tmp=1ll*a[j][i]*qpow(a[i][i],mod-)%mod;
for(int k=i;k<=n;k++)
a[j][k]=(a[j][k]-1ll*a[i][k]*tmp%mod+mod)%mod;
}
}
} int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=n;j++)
if(s[j]=='')a[j][i]=-,a[j][j]++;
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(a[i][j]<)a[i][j]+=mod;
Gauss();
for(int i=;i<=n;i++)
ans=1LL*ans*a[i][i]%mod;
printf("%d",ans);
}

【bzoj4031】[HEOI2015]小Z的房间 && 【bzoj4894】天赋 (矩阵树定理)的更多相关文章

  1. BZOJ4031 [HEOI2015]小Z的房间 【矩阵树定理 + 高斯消元】

    题目链接 BZOJ4031 题解 第一眼:这不裸的矩阵树定理么 第二眼:这个模\(10^9\)是什么鬼嘛QAQ 想尝试递归求行列式,发现这是\(O(n!)\)的.. 想上高斯消元,却又处理不了逆元这个 ...

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

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

  3. bzoj4031 [HEOI2015]小Z的房间

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

  4. BZOJ4894:天赋(矩阵树定理)

    Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的. 也就是说,有一些天赋必须是要在 ...

  5. bzoj4031 [HEOI2015]小Z的房间——矩阵树定理

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4031 矩阵树定理的模板题(第一次的矩阵树定理~): 有点细节,放在注释里了. 代码如下: # ...

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

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

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

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

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

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

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

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

随机推荐

  1. C++中malloc / free 和 new / delete 的区别?

    1.malloc/free 是C++/C语言的标准库函数,New/delete是C++运算符:都是用于申请动态内存和释放内存. 2.new做两件事:分配内存和调用类的构造函数,delete是:调用类的 ...

  2. Java中的Static修饰符

    static(静态.修饰符):static修饰成员变量时:static修饰成员变量时,那么该成员变量的数据就是一个共享的数据. 静态成员变量的访问方式:方式一: 使用对象进行访问. 对象.属性名 方式 ...

  3. Codevs3324 新斯诺克

    题目描述 Description 斯诺克又称英式台球,是一种流行的台球运动.在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分别为1 个白球,15 个红球和6 个彩球(黄.绿.棕.蓝.粉红. ...

  4. NOIP模拟赛 抓牛

    [题目描述] 农夫约翰被通知,他的一只奶牛逃逸了!所以他决定,马上出发,尽快把那只奶牛抓回来. 他们都站在数轴上.约翰在N(O≤N≤100000)处,奶牛在K(O≤K≤100000)处.约翰有两种办法 ...

  5. 【思维题 状压dp】APC001F - XOR Tree

    可能算是道中规中矩的套路题吧…… Time limit : 2sec / Memory limit : 256MB Problem Statement You are given a tree wit ...

  6. [51nod] 1301 集合异或和

    考虑不限制xor{Y}>xor{X} 考虑n=m的情况,每个数i∈[1,n]可以被分配到X集合或Y集合,或不分配 设f[S]表示{X} xor {Y} == S的方案数 有f[S]+=2*f[S ...

  7. PHP安装Xcache扩展

    简述 XCache 是一个又快又稳定的 ​PHP opcode 缓存器. 经过良好的测试并在大流量/高负载的生产机器上稳定运行. 经过(在 linux 上)测试并支持所有现行 ​PHP 分支的最新发布 ...

  8. python日记整理

    都是自己的学习总结,要是总结的有问题大佬麻烦评价一下我好修改,谢谢 python插件插件+pycharm基本用法+markdown文本编写+jupyter notebook的基本操作汇总 一.计算机基 ...

  9. SPOJ375 Query on a tree(树链剖分)

    传送门 题意 给出一棵树,每条边都有权值,有两种操作: 把第p条边的权值改为x 询问x,y路径上的权值最大的边 code #include<cstdio> #include<algo ...

  10. 关于freetype在安装中的遇到的问题

    本人电脑配置的是Anconda环境+pycharm2017.2.2 comuniity,每次安装什么包就是直接pip install 的,但是这次在安装freetype的安装中却遇到了麻烦. 具体是在 ...