uva10766生成树计数(矩阵树定理)

更正了我之前打错的地方,有边的话G[i][j]=-1;

WA了好多次,中间要转成long double才行。。这个晚点更新。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 typedef long double ld;
 8 
 9 const int N=60;
10 const ld eps=1e-9;
11 int map[N][N];
12 ld G[N][N];
13 
14 ld myabs(ld x){return x>0 ? x:-x;}
15 
16 ld guass(int n)
17 {
18     ld ans=1;
19     for(int i=1;i<=n;i++)
20     {
21         int r=i;
22         for(int j=i+1;j<=n;j++)
23             if(myabs(G[j][i]) > myabs(G[r][i])) r=j;
24         if(r!=i)
25         {
26             for(int j=1;j<=n;j++) swap(G[i][j],G[r][j]);
27             ans*=-1;
28         }
29         if(myabs(G[i][i])<eps) return 0;
30         for(int j=i+1;j<=n;j++)
31             for(int k=n;k>=i;k--)
32                 G[j][k]-=G[j][i]/G[i][i]*G[i][k];
33     }
34     for(int i=1;i<=n;i++) ans*=G[i][i];
35     return myabs(ans);
36 }
37 
38 int main()
39 {
40     //freopen("a.in","r",stdin);
41     int n,m,k;
42     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
43     {
44         int x,y;
45         memset(map,0,sizeof(map));
46         memset(G,0,sizeof(G));
47         for(int i=1;i<=m;i++)
48         {
49             scanf("%d%d",&x,&y);
50             map[x][y]=map[y][x]=1;
51         }
52         for(int i=1;i<=n;i++)
53             for(int j=1;j<i;j++)
54                 if(!map[i][j]) 
55                 {
56                     G[i][j]=-1;G[j][i]=-1;
57                     G[i][i]++;G[j][j]++;
58                 }
59         printf("%.0lf
",(double)guass(n-1));
60     }
61     return 0;
62 }
原文地址:https://www.cnblogs.com/KonjakJuruo/p/9674099.html