矩阵树定理
Tangninghaha · · 算法·理论
简介
基尔霍夫矩阵树定理(简称作矩阵树定理)用于对给定图的生成树数量进行计数。
该定理使得只需要进行一次行列式求值就可以得到一个图的生成树数量。
本文旨在直观的理解矩阵树定理,如果希望得到较为严格的定义与证明,可以阅读 这篇文章。
定理内容
在该定理中不允许自环,允许重边。
给定图的邻接矩阵为
给定图的度数矩阵为
定义无向图的拉普拉斯 (Laplace) 矩阵
有向图的入度拉普拉斯矩阵
那么,有结论:
定理1:无向图的拉普拉斯矩阵的任意
定理2:有向图以
定理3:有向图以
证明
不会
参考代码
下面给出 模板题 的参考代码。
#include<bits/stdc++.h>
using namespace std;
const int N=305,mod=1e9+7;
int n;
int a[N][N];
int main(){
int n,m,t;
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=m;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
if(t){
a[v][v]+=w;
if(a[v][v]>=mod)a[v][v]-=mod;
a[u][v]-=w;
if(a[u][v]<0)a[u][v]+=mod;
}else{
a[u][u]+=w;
if(a[u][u]>=mod)a[u][u]-=mod;
a[v][v]+=w;
if(a[v][v]>=mod)a[v][v]-=mod;
a[u][v]-=w;
if(a[u][v]<0)a[u][v]+=mod;
a[v][u]-=w;
if(a[v][u]<0)a[v][u]+=mod;
}
}
int neg=1;
for(int i=2;i<=n;++i){
for(int j=i+1;j<=n;++j){
while(a[i][i]){
int t=a[j][i]/a[i][i];
for(int k=i;k<=n;++k){
a[j][k]-=1ll*t*a[i][k]%mod;
if(a[j][k]<0)a[j][k]+=mod;
}
swap(a[i],a[j]);
neg*=-1;
}
swap(a[i],a[j]);
neg*=-1;
}
}
int ans=1;
for(int i=2;i<=n;++i)ans=1ll*ans*a[i][i]%mod;
ans=(ans*neg%mod+mod)%mod;
printf("%d\n",ans);
}