生成树计数 UVA 10766

 1 //本题题意:首先每个点之间都可达,然后m列举出不可达的,求出最多的生成树方案;
 2 //k这个变量是没用的。
 3 //公式:ans矩阵=度矩阵-建边矩阵;
 4 //度矩阵是当i==j时的,建边矩阵于平时定义可达矩阵相同
 5 #include<stdio.h>
 6 #include<string.h>
 7 #include<math.h>
 8 #include<algorithm>
 9 using namespace std;
10 #define INF 0x3f3f3f3f
11 #define LL long long int
12 const int MAXN=55;
13 LL A[MAXN][MAXN];
14 LL B[MAXN][MAXN];
15 LL determinant(int n)
16 {
17     LL res=1;
18     for(int i=1;i<=n;i++){
19         if(!B[i][i]){
20             bool flag=false;
21             for(int j=i+1;j<=n;j++){
22                 if(B[j][i]){
23                     flag=true;
24                     for(int k=i;k<n;k++){
25                         swap(B[i][k],B[j][k]);
26                     }
27                     res=-res;
28                     break;
29                 }
30             }
31             if(!flag)
32             return 0;
33         }
34         for(int j=i+1;j<=n;j++){
35             while(B[j][i]){
36                 LL t=B[i][i]/B[j][i];
37                 for(int k=i;k<=n;k++){
38                     B[i][k]=B[i][k]-t*B[j][k];
39                     swap(B[i][k],B[j][k]);
40                 }
41                 res=-res;
42             }
43         }
44         res*=B[i][i];
45     }
46     return res;
47 }
48 int main()
49 {
50     int n,m,k;
51     while(~scanf("%d%d%d",&n,&m,&k))//这个k没卵用,完全可以无视 
52     {   
53         memset(A,0,sizeof(A));
54         memset(B,0,sizeof(B));
55         for(int i=1;i<=m;i++){
56             int a,b;
57             scanf("%d%d",&a,&b);
58             A[a][b]=A[b][a]=1;
59         }
60         for(int i=1;i<=n;i++){
61             for(int j=1;j<=n;j++){
62                 if(i!=j&&!A[i][j]){
63                     B[i][i]++;
64                     B[i][j]=-1;//减去邻接矩阵 
65                 }
66             }
67         }
68         n=n-1;
69         LL ans=determinant(n); 
70         printf("%lld\n",ans);
71     }
72     return 0;
73 }

 

posted @ 2019-10-18 22:50  古比  阅读(155)  评论(0编辑  收藏  举报