MatrixTree定理是用來解決生成樹計數問題的有利工具ios
好比說這道題算法
MatrixTree定理的算法流程也很是簡單工具
咱們記矩陣\(A\)爲無向圖的度數矩陣
記矩陣\(D\)爲無向圖的鄰接矩陣spa
\(A\)矩陣是除了對角線以外各個點值都爲\(0\)的矩陣,\(A[i][i]\)表示\(i\)號點的度數code
\(D\)矩陣記錄兩點之間的度數,\(D[i][j]\)表示\(i\)號點與\(j\)號點之間的邊數get
咱們記矩陣\(G=A-D\)
那麼\(G\)的全部不一樣生成樹的個數等於\(G\)的任何一個 \(n-1\) 階主子式的行列式的絕對值string
MatrixTree定理的實現很是簡單io
就是上面那道題目的代碼class
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> using namespace std; const int MAXN=3001; const double eps=1e-12; inline int read() { char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } double G[MAXN][MAXN],a[MAXN][MAXN]; char s[MAXN][MAXN]; int xx[5]={0,-1,+1,0,0}; int yy[5]={0,0,0,-1,+1}; int N,M; int dcmp(int x) { if(x<=eps||x>=-eps) return 0; else return x<0?-1:1; } void Gauss() { N--; for(int i=1;i<=N;i++)//每一行 { int mx=i; for(int j=i+1;j<=N;j++)//下面的每一行 if(dcmp(G[mx][i]-G[j][i])<0) mx=j; if(mx!=i) swap(G[i],G[mx]); if(!G[i][i]) {printf("0\n");return ;} for(int j=i+1;j<=N;j++) { double t=G[j][i]/G[i][i]; for(int k=i;k<=N+1;k++) G[j][k]-=t*G[i][k]; } } double ans=1; for(int i=1;i<=N;i++) ans=ans*G[i][i]; printf("%.0f\n",abs(ans)); } int main() { int T=read(); while(T--) { memset(G,0,sizeof(G)); N=read(),M=read(); for(int i=1;i<=M;i++) { int x=read(),y=read(); G[x][x]++;G[y][y]++; G[x][y]--;G[y][x]--; } Gauss(); } return 0; }