生成树计数模板 spoj 104 (不用逆元的模板)
1 /* 2 这种题,没理解,只是记一记如何做而已; 3 生成树的计数--Matrix-Tree定理 4 5 题目:SPOJ104(Highways) 6 题目大意: 7 *一个有n座城市的组成国家,城市1至n编号,其中一些城市之间可以修建高速公路; 8 *需要有选择的修建一些高速公路,从而组成一个交通网络; 9 *计算有多少种方案,使得任意两座城市之间恰好只有一条路径; 10 11 步骤: 先按输入数据建图:C[u][v]=C[v][u]=-1;degree[u]++; degree[v]++; 12 再去掉一行一列,用计算行列式的某个方法去计算就好了。。 13 */ 14 15 #include<bits/stdc++.h> 16 using namespace std; 17 const int N=15; 18 typedef long long LL; 19 int degree[N]; 20 LL C[N][N]; 21 LL det(LL a[][N],int n){ 22 LL ret=1; 23 for(int i=1; i<n; i++){ //从一开始,去掉了0这一列; 24 for(int j=i+1; j<n; j++) 25 while(a[j][i]){ 26 LL t=a[i][i]/a[j][i]; 27 for(int k=i; k<n; k++) 28 a[i][k]=(a[i][k]-a[j][k]*t); 29 for(int k=i; k<n; k++) 30 swap(a[i][k],a[j][k]); 31 ret=-ret; 32 } 33 if(a[i][i]==0)return 0; 34 ret=ret*a[i][i]; 35 } 36 if(ret<0)ret=-ret; 37 return ret; 38 } 39 int main(){ 40 int tcase;cin>>tcase; 41 while(tcase--){ 42 memset(degree,0,sizeof(degree)); 43 memset(C,0,sizeof(C)); 44 int n,m,u,v; 45 scanf("%d%d",&n,&m); 46 while(m--){ 47 scanf("%d%d",&u,&v); 48 u--;v--; 49 C[u][v]=C[v][u]=-1; 50 degree[u]++; 51 degree[v]++; 52 } 53 for(int i=0; i<n; ++i) 54 C[i][i]=degree[i]; 55 printf("%lld\n",det(C,n)); 56 } 57 return 0; 58 } 59 /* 60 input: output: 61 4 8 62 4 5 1 63 3 4 1 64 4 2 3 65 2 3 66 1 2 67 1 3 68 69 2 1 70 2 1 71 72 1 0 73 74 3 3 75 1 2 76 2 3 77 3 1 78 */