SPOJ#104. [矩阵树定理]Highways
Problem:
给定一个无向图,求其不同的生成树个数
Solution:
定义A邻接矩阵,D度数矩阵,C基尔霍夫矩阵
C=D-A
根据Matrix-tree定理:生成树个数等于基尔霍夫矩阵的n-1阶矩阵的行列式绝对值
所以我们的C矩阵只用保存n-1位
再用Guass化成上三角矩阵
对角线的乘积的绝对值就是答案
附上代码:
#include<bits/stdc++.h> using namespace std; const double eps=1e-9; const int N=25; int A[N][N],D[N][N];//A是邻接矩阵,D是度数矩阵 double C[N][N];//C是基尔霍夫矩阵 int n,m; void gauss() { int now=1; for(int i=1;i<=n;i++) { int x=now; while(fabs(C[x][now])<eps&&x<=n) x++; if(x==n+1) {puts("0");return ;} for(int j=1;j<=n;j++) swap(C[x][j],C[now][j]); for(int j=now+1;j<=n;j++) { double temp=C[j][now]/C[now][now]; for(int k=1;k<=n;k++) C[j][k]=C[j][k]-C[now][k]*temp; } now++; } double ans=1; for(int i=1;i<=n;i++) ans*=C[i][i]; ans=fabs(ans); printf("%.0lf\n",ans); } int main() { freopen("a.in","r",stdin); int T;scanf("%d",&T); while(T--) { memset(A,0,sizeof(A)); memset(D,0,sizeof(D)); scanf("%d%d",&n,&m);n--; for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); D[x][x]++;D[y][y]++; A[x][y]++;A[y][x]++; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) C[i][j]=D[i][j]-A[i][j]; gauss(); } return 0; }