spoj 104 Highways(Matrix-tree定理)

 

spoj 104 Highways

 

生成树计数,matrix-tree定理的应用。

Matrix-tree定理:

D为无向图G的度数矩阵(D[i][i]是i的度数,其他的为0),A为G的邻接矩阵(若u,v之间存在边,A[u][v]=A[v][u]=1),C=D-A。

对于一个无向图G,它的生成树个数等于其Kirchhoff矩阵任何一个n-1阶主子式的行列式的绝对值。 所谓n-1阶主子式,就是对于任意一个r,将C的第r行和第r列同表示时删去后的新矩阵,表示为Cr。

求行列式的值:

把矩阵用高斯消元消成上三角矩阵,对角线的积就是行列式的值。

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 
 7 using namespace std;
 8 
 9 const double eps = 1e-15;
10 
11 double c[20][20];
12 int T,n,m;
13 
14 double Gauss() {
15     for (int k=1; k<=n; ++k) {
16         int r = k;
17         for (int i=k+1; i<=n; ++i) 
18             if (fabs(c[i][k]) > fabs(c[r][k])) r = i;
19         if (r!=k) for (int j=1; j<=n; ++j) swap(c[k][j],c[r][j]);
20         for (int i=k+1; i<=n; ++i) 
21             if (fabs(c[i][k]) > eps) {
22                 double t = c[i][k] / c[k][k];
23                 for (int j=k; j<=n; ++j) c[i][j] -= t*c[k][j];
24             }
25     }
26     double ans = 1.0;
27     for (int i=1; i<=n; ++i) ans = ans*c[i][i]; //矩阵的对角线乘积
28     return (ans > 0) ? ans : -ans;//取绝对值
29 }
30 
31 int main() {
32     scanf("%d",&T);
33     while (T--) {
34         memset(c,0,sizeof(c));
35         scanf("%d%d",&n,&m);
36         for (int u,v,i=1; i<=m; ++i) {
37             scanf("%d%d",&u,&v);
38             c[u][v] = c[v][u] = -1;//
39             c[u][u] ++;c[v][v] ++;//度数
40         }
41         n--; // 去掉最后一行最后一列
42         double ans = Gauss(); //高斯消元
43         printf("%.0lf\n",ans+eps);
44     }
45     return 0;
46 }

 

转载于:https://www.cnblogs.com/mjtcn/p/8502826.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值