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

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

学习资源:

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. 【BZOJ4870】组合数问题(计数DP,快速幂)

    题意: 1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1 思路:From http://blog.csdn.net/qq_33229466/artic ...

  2. 【BZOJ】2631: tree LCT

    [题意]给定n个点的树,每个点初始权值为1,m次操作:1.x到y的点加值,2.断一条边并连一条边,保证仍是树,3.x到y的点乘值,4.x到y的点权值和取模.n,m<=10^5. [算法]Link ...

  3. parseInt

    本文地址:http://www.cnblogs.com/veinyin/p/7647863.html 先来个简单的 console.log(parseFloat("8")); 嗯, ...

  4. HNOI2019退役祭

    对你没看错,是退役祭. Day -2 春游.话说为什么又是植物园? Day -1 白天上文化课,晚上给机房其它童鞋出题. Day 0 给他们考试,然后颓3Dmaze,毕竟没网 Day 1 车上复习了下 ...

  5. Chrome浏览器任意修改网页内容

    在Chrome浏览器按F12,打开开发者工具,切换到console选项卡: 在下面的输入行输入下面的命令回车: document.body.contentEditable="true&quo ...

  6. Django(基础篇)

    1.请求周期 url> 路由 > 函数或类 > 返回字符串或者模板语言? Form表单提交:        提交 -> url > 函数或类中的方法           ...

  7. 利用Jsoup模拟跳过登录爬虫获取数据

    今天在学习爬虫的时候想着学习一下利用jsoup模拟登录.下面分为有验证码和无验证码的情况进行讨论. ---------------------------无验证码的情况---------------- ...

  8. Shell-history命令加记录用户IP

    记录输入的命令 history命令可以查看用户输入过的命令,一个典型history命令输出如下: 980 2017-05-29 20:17:37 cd - 981 2017-05-29 20:17:4 ...

  9. CentOS测网速

    当发现上网速度变慢时,人们通常会先首先测试自己的电脑到网络服务提供商(通常被称为"最后一公里")的网络连接速度.在可用于测试宽带速度的网站中,Speedtest.net也许是使用最 ...

  10. WebBrowser中运行js

    HtmlElement script = wf.WebBrowser.Document.CreateElement("script"); script.SetAttribute(& ...