圖論學習:生成樹的Matrix-tree定理
阿新 • • 發佈:2020-08-13
前置知識:矩陣的代數餘子式,拉普拉斯矩陣(基爾霍夫矩陣),證明的話還需要用到關聯矩陣、柯西——比內公式等
此處剛開始介紹的是沒有重邊和自環的無向圖
1.代數餘子式:
2.拉普拉斯矩陣
如:
3.矩陣數定理:
無向圖的生成樹個數就等於這副圖的拉普拉斯矩陣的任意一個代數餘子式值。
4.拉普拉斯矩陣的性質
定理1:拉普拉斯矩陣的任意一個代數餘子式值都相同
定理2:拉普拉斯矩陣的行列式為0
根據定理1,我們只需要證明 \({C}_{1,1}\)是圖的生成樹個數就好了。
這裡不寫具體證明,想要知道的可以去自行了解
5.推廣:
6.模板和例題:
1.Highways
模板:求無向圖的最小生成樹個數(無重邊和自環)
點選檢視程式碼塊
/* 矩陣樹定理: 無向圖的生成樹個數就等於這副圖的拉普拉斯矩陣的任意一個代數餘子式值。 */ #include <bits/stdc++.h> #define ed end() #define bg begin() #define mkp make_pair #define pb push_back #define v(T) vector<T> #define all(x) x.bg,x.ed #define newline puts("") #define si(x) ((int)x.size()) #define rep(i,n) for(int i=1;i<=n;++i) #define rrep(i,n) for(int i=0;i<n;++i) #define srep(i,s,t) for(int i=s;i<=t;++i) using namespace std; typedef long long ll; typedef pair<int,int> pii; const int maxn = 50; const int inf = 0x7f7f7f7f; const ll inf_ll = 1ll*inf*inf; const int Mod = 1e9+7; const double eps = 1e-7; int n,m; int g[maxn][maxn]; ll L[maxn][maxn]; ll det(int n){ ll ret = 1; for (int i=2;i<=n;i++){ for (int j=i+1;j<=n;j++){ while(L[j][i]){ ll tmp=L[i][i]/L[j][i];//不存在除不盡的情況 for(int k=i;k<=n;k++) L[i][k] -= tmp*L[j][k]; for(int k=i;k<=n;k++) swap(L[i][k],L[j][k]); ret = -ret; } } if(!L[i][i]) return 0; ret *= L[i][i]; } if(ret < 0) ret = -ret; return ret; } int main(){ int T; scanf("%d",&T); for(int _=1;_<=T;_++) { memset(g,0,sizeof(g)); memset(L,0,sizeof(L)); scanf("%d%d",&n,&m); rep(i,m){ int u,v; scanf("%d%d",&u,&v); g[u][v]=g[v][u]=1; } for (int i=1;i<=n;i++){ for (int j=i;j<=n;j++){ if(g[i][j]){ L[i][i]++;L[j][j]++; L[i][j]--;L[j][i]--; } } } ll ans = det(n); printf("%lld\n",ans); } return 0; }
點選檢視程式碼塊