如果不谈证明,稍微有点线代基础的人都可以在两分钟内学完所有相关内容。。

行列式随便找本线代书看一下基本性质就好了。

学习资源:

https://www.cnblogs.com/candy99/p/6420935.html

http://blog.csdn.net/Marco_L_T/article/details/72888138

首先是行列式对几个性质(基本上都是用数学归纳法证):

1.交换两行(列),行列式取相反数

2.由1.得若存在两行(列)完全相同则行列式为0

3.上(下)三角行列式即主对角线值之积

只有这三条用得上。

然后就可以直接上Matrix Tree定理了:一个无向图的邻接矩阵减去度数矩阵得到的矩阵的任意n-1阶子矩阵的行列式的绝对值等于其有标号生成树的数目。

其中邻接矩阵-度数矩阵即为基尔霍夫矩阵(又称拉普拉斯算子)。

加强版:有向图的树形图(从根可以走到任意点)个数,将上面的“度数矩阵”改为“入度矩阵即可”(见第二份链接)

若求以x为根的外向树数量,则求删去第x行与第x列的n-1阶子矩阵的行列式即可。

关于行列式的算法,按定义朴素跑复杂度是阶乘级别的,利用上面的性质,初等行变换使之成为上三角矩阵即可。(实际上就是高斯消元)。注意高消中基准元要选绝对值最大的,以及注意判0退出。

下面是几道裸题:

SPOJ Highways  裸题

 #include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
using namespace std; const int N=;
const double eps=1e-; int T,n,m,u,v;
double a[N][N]; void Gauss(){
n--;
rep(i,,n){
int r=i;
rep(j,i+,n) if (fabs(a[j][i])>fabs(a[r][i])) r=j;
if (fabs(a[r][i]<eps)) { puts(""); return; }
if (r!=i) rep(k,,n) swap(a[r][k],a[i][k]);
rep(j,i+,n){
double t=a[j][i]/a[i][i];
rep(k,i,n) a[j][k]-=t*a[i][k];
}
}
double ans=;
rep(i,,n) ans*=a[i][i];
printf("%.0f\n",abs(ans));
} int main(){
for (scanf("%d",&T); T--; ){
scanf("%d%d",&n,&m);
memset(a,,sizeof(a));
rep(i,,m) scanf("%d%d",&u,&v),a[u][u]++,a[v][v]++,a[u][v]--,a[v][u]--;
Gauss();
}
return ;
}

BZOJ4766:

先手工构造出矩阵然后观察规律求出公式。

https://blog.sengxian.com/solutions/bzoj-4766

 #include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll; ll n,m,P;
ll mod(ll x){ return (x<P) ? x : x-P; } ll mul(ll a,ll b){
ll res=;
for (; b; b>>=,a=mod(a+a))
if (b & ) res=mod(res+a);
return res;
} ll pow(ll a,ll b){
ll res=;
for (; b; b>>=,a=mul(a,a))
if (b & ) res=mul(res,a);
return res;
} int main(){
scanf("%lld%lld%lld",&n,&m,&P);
printf("%lld\n",mul(pow(n,m-),pow(m,n-)));
return ;
}

BZOJ4031 裸题

这里又个trick,高斯消元的时候因为模数是个合数不好求逆元,所以用辗转相除的方法做就好了。

就是不停对两行相互进行初等行变换直到其中一行第一个数变为0,这样复杂度是log的,并且保证膜意义下不会出错。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const int N=,md=;
int n,m,a[N][N],id[N][N],tot;
char s[N][N]; void Gauss(int n){
int s=;
rep(i,,n){
int r=i;
rep(j,i+,n) if (a[j][i]>a[r][i]) r=j;
if (!a[r][i]) { puts(""); return; }
if (i!=r){
s^=;
rep(k,i,n) swap(a[i][k],a[r][k]);
}
rep(j,i+,n){
while (a[j][i]){
ll t=a[j][i]/a[i][i];
rep(k,i,n) a[j][k]=(a[j][k]-t*a[i][k]%md+md)%md;
if (!a[j][i]) break;
s^=;
rep(k,i,n) swap(a[i][k],a[j][k]);
}
}
}
ll ans=;
rep(i,,n) ans=ans*a[i][i]%md;
if (s) ans=(md-ans)%md;
printf("%lld\n",ans);
} void work(){
rep(i,,m) rep(j,,n) if (s[i][j]=='.') id[i][j]=++tot;
rep(i,,m) rep(j,,n) if (id[i][j]){
int u=id[i][j],v;
if (i!= && s[i-][j]=='.')
v=id[i-][j],a[u][u]++,a[v][v]++,a[u][v]--,a[v][u]--;
if (j!= && s[i][j-]=='.')
v=id[i][j-],a[u][u]++,a[v][v]++,a[u][v]--,a[v][u]--;
}
rep(i,,m*n) rep(j,,m*n) a[i][j]=(a[i][j]+md)%md;
} int main(){
freopen("bzoj4031.in","r",stdin);
freopen("bzoj4031.out","w",stdout);
scanf("%d%d",&m,&n);
rep(i,,m) scanf("%s",s[i]+);
work(); Gauss(tot-);
return ;
}

矩阵树定理(Matrix Tree)学习笔记的更多相关文章

  1. 【Learning】矩阵树定理 Matrix-Tree

    矩阵树定理 Matrix Tree ​ 矩阵树定理主要用于图的生成树计数. 看到给出图求生成树的这类问题就大概要往这方面想了. 算法会根据图构造出一个特殊的基尔霍夫矩阵\(A\),接着根据矩阵树定理, ...

  2. @总结 - 7@ 生成树计数 —— matrix - tree 定理(矩阵树定理)与 prüfer 序列

    目录 @0 - 参考资料@ @0.5 - 你所需要了解的线性代数知识@ @1 - 矩阵树定理主体@ @证明 part - 1@ @证明 part - 2@ @证明 part - 3@ @证明 part ...

  3. 【算法】Matrix - Tree 矩阵树定理 & 题目总结

    最近集中学习了一下矩阵树定理,自己其实还是没有太明白原理(证明)类的东西,但想在这里总结一下应用中的一些细节,矩阵树定理的一些引申等等. 首先,矩阵树定理用于求解一个图上的生成树个数.实现方式是:\( ...

  4. 矩阵树定理&BEST定理学习笔记

    终于学到这个了,本来准备省选前学来着的? 前置知识:矩阵行列式 矩阵树定理 矩阵树定理说的大概就是这样一件事:对于一张无向图 \(G\),我们记 \(D\) 为其度数矩阵,满足 \(D_{i,i}=\ ...

  5. Note -「矩阵树定理」学习笔记

      大概--会很简洁吧 qwq. 矩阵树定理   对于无自环无向图 \(G=(V,E)\),令其度数矩阵 \(D\),邻接矩阵 \(A\),令该图的 \(\text{Kirchhoff}\) 矩阵 \ ...

  6. 珂朵莉树(Chtholly Tree)学习笔记

    珂朵莉树(Chtholly Tree)学习笔记 珂朵莉树原理 其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......) ...

  7. 2018.09.16 spoj104Highways (矩阵树定理)

    传送门 第一次写矩阵树定理. 就是度数矩阵减去邻接矩阵之后得到的基尔霍夫矩阵的余子式的行列式值. 这个可以用高斯消元O(n3)" role="presentation" ...

  8. luoguP3317 [SDOI2014]重建 变元矩阵树定理 + 概率

    首先,我们需要求的是 $$\sum\limits_{Tree} \prod\limits_{E \in Tree} E(u, v) \prod\limits_{E \notin Tree} (1 - ...

  9. 【BZOJ4894】天赋(矩阵树定理)

    [BZOJ4894]天赋(矩阵树定理) 题面 BZOJ Description 小明有许多潜在的天赋,他希望学习这些天赋来变得更强.正如许多游戏中一样,小明也有n种潜在的天赋,但有 一些天赋必须是要有 ...

随机推荐

  1. 【CODEVS】1033 蚯蚓的游戏问题

    [算法]网络流-最小费用最大流(费用流) [题解]与方格取数2类似 在S后添加辅助点S_,限流k 每条边不能重复走,限流1 #include<cstdio> #include<alg ...

  2. 【BZOJ】1951[Sdoi2010]古代猪文

    [题意]给定G,N,求: $$ans=G^{\sum_{i|n}\binom{n}{i}}\ \mod\ \ p$$ 1<=N,G<=10^9,p=999911659. [算法]欧拉定理+ ...

  3. 【51nod】1222 最小公倍数计数 莫比乌斯反演+组合计数

    [题意]给定a和b,求满足a<=lcm(x,y)<=b && x<y的数对(x,y)个数.a,b<=10^11. [算法]莫比乌斯反演+组合计数 [题解]★具体 ...

  4. laravel artisan 工具心得

    介绍一些非常好用的命令: 1.创建一个Eloquent模型:顺便创建一个对应的数据库表 php artisan make:model --migration Models/Admin/test 2.将 ...

  5. VC字体对话框的初始化

    本代码需要先添加类成员  LOGFONT lf; void CMyDlg::OnButton3() { // TODO: Add your control notification handler c ...

  6. IE9 下 ellipsis bug fix

    fiddle: http://jsfiddle.net/tagliala/TtbuG/10/ original: https://github.com/FortAwesome/Font-Awesome ...

  7. 005zabbix3.0报错记录

    一.问题描述 在zabbix_server添加变量时,出现了以下的报错,

  8. Django实现文章按年月归档、点赞和评论、发送邮件

    文章归档的实现 我们在创建文章时,会在数据库中存储文章创建的时间这样的字段,一般用的都是datetime类型,记录文章创建的年月日和时分秒,所以我们直接使用文章的创建时间分类是无法实现文章的按年月归档 ...

  9. Mysql中的Btree与Hash索引

    B-Tree 索引特征 B-Tree索引可以被用在像=,>,>=,<,<=和BETWEEN这些比较操作符上.而且还可以用于LIKE操作符,只要它的查询条件是一个不以通配符开头的 ...

  10. Node.js fs-文件系统

    fs.stat,获取文件信息. var fs = require('fs') fs.stat('../index.js', (err, stats) => { if (err) { consol ...