SPOJ - HIGH Highways(矩阵树定理)

Posted 谦谦君子,陌上其华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ - HIGH Highways(矩阵树定理)相关的知识,希望对你有一定的参考价值。

https://vjudge.net/problem/SPOJ-HIGH

题意:

给n个点m条边,求生成树个数。

 

思路:

矩阵树裸题。

具体的话可以看一下周冬的论文《生成树的计数及其应用》。

简单说一下,$A[ ][ ]$为邻接矩阵,有边为1(其实也就是边的个数,有重边时要注意),无边为0。$D[ ][ ]$为度数矩阵,$i=j$时为1,否则为0。

$C[ ][ ]$为关联矩阵,$C[ ][ ]=D[ ][ ]-A[ ][ ]$。

最后解任意n-1阶的主子式即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,ll> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn=1000+5;
17 
18 int n,m;
19 double C[maxn][maxn];
20 int A[maxn][maxn],D[maxn][maxn];
21 
22 double Gauss()
23 {
24     for(int k=1; k<=n; k++)  //k表示当前行数,因为行数与列数一样,所以这里k也代表了列数
25     {
26         int max_r=k;
27         for(int i=k+1;i<=n;i++)
28             if(fabs(C[i][k]>fabs(C[max_r][k])))  max_r=i;
29         if(C[max_r][k]==0)  return 0;  //有一列为0,行列式的值必为0
30         if(max_r!=k)
31         {
32             for(int j=k;j<=n;j++)
33                 swap(C[k][j],C[max_r][j]);
34         }
35         for(int i=k+1;i<=n;i++)
36         {
37             double tmp=C[i][k]/C[k][k];
38             for(int j=k;j<=n;j++)
39                 C[i][j]-=tmp*C[k][j];
40         }
41     }
42     double ans=1;
43     for(int i=1;i<=n;i++)  ans*=C[i][i];  //化为三角阵后计算主对角线元素乘积
44     ans=fabs(ans);
45     return ans;
46 }
47 
48 int main()
49 {
50     //freopen("in.txt","r",stdin);
51     int T;
52     scanf("%d",&T);
53     while(T--)
54     {
55         memset(A,0,sizeof(A));
56         memset(D,0,sizeof(D));
57         scanf("%d%d",&n,&m);
58         for(int i=0;i<m;i++)
59         {
60             int u,v;
61             scanf("%d%d",&u,&v);
62             D[u][u]++; D[v][v]++;
63             A[u][v]++; A[v][u]++;
64         }
65         n--;
66         for(int i=1;i<=n;i++)
67         for(int j=1;j<=n;j++)
68             C[i][j]=D[i][j]-A[i][j];
69         printf("%.0lf\n",Gauss());
70     }
71     return 0;
72 }

 

以上是关于SPOJ - HIGH Highways(矩阵树定理)的主要内容,如果未能解决你的问题,请参考以下文章

SPOJ - HIGH :Highways (生成树计数)

无向图生成树计数 基尔霍夫矩阵 SPOJ Highways

[spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)

spoj 106 Highways (最小生成树计数)

spoj 104 Highways(Matrix-tree定理)

SP104 HIGH - Highways