Uva 10766 Organising the Organisation (Matrix_tree 生成树计数)

题目描述:

  一个由n个部门组成的公司现在需要分层,但是由于员工间的一些小小矛盾,使得他们并不愿意做上下级,问在满足他们要求以后有多少种分层的方案数?

解题思路:

  生成树计数模板题,建立Kirchhoff矩阵,利用Matrix_tree定理求解。

  Kirchhoff矩阵:假设G为n*n矩阵,C为G的入度矩阵(i==j时,C[i][j]等于i的入度;i!=j时,C[i][j]等于零),A为G的邻接矩阵,那么就有Kirchhoff矩阵等于C-A。

  Matrix_tree定理:G的不同生成树的个数等于其所对应的kirchhoff矩阵的n-1阶行列式的绝对值(PS:n-1阶行列式等于Kirchhoff矩阵减去第r行,第r列后所形成的矩阵,其中1<=r<=n)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long double LD;
 7 const int maxn = 60;
 8 const LD sng = 1e-8;
 9 
10 LD b[maxn][maxn];
11 int a[maxn][maxn];
12 bool Exp(LD x)
13 {
14     return ((x>=0)?x:-x)<sng;
15 }
16 LD MTree (int n)
17 {
18     int sign = 0, j;
19     LD res = 1;
20     for (int i=0; i<n; i++)
21     {
22         if (Exp(b[i][i]))
23         {
24             for (j=i+1; j<n; j++)
25                 if (!Exp(b[j][i]))
26                     break;
27             if (j == n)
28                 return 0;
29             for (int k=i; k<n; k++)
30                 swap (b[i][k], b[j][k]);
31             sign ++;
32         }
33         res *= b[i][i];
34         for (j=i+1; j<n; j++)
35             b[i][j] /= b[i][i];
36         for (j=i+1; j<n; j++)
37             for (int k=i+1; k<n; k++)
38                 b[j][k] -= b[j][i] * b[i][k];
39     }
40     if (sign % 2)
41         res = -res;
42     return res;
43 }
44 int main ()
45 {
46     int n, m, k;
47     while (scanf ("%d %d %d", &n, &m, &k) != EOF)
48     {
49         memset (a, 0, sizeof(a));
50         memset (b, 0, sizeof(b));
51         while (m --)
52         {
53             int u, v;
54             scanf ("%d %d", &u, &v);
55             u--, v--;
56             a[u][v] = a[v][u] = 1;
57         }
58         for (int i=0; i<n; i++)
59             for (int j=0; j<n; j++)
60                 if (!a[i][j] && i != j)
61                 {
62                     b[i][i] ++;
63                     b[i][j] = -1;
64                 }
65         printf ("%.0f\n", (double)MTree (n - 1));
66     }
67     return 0;
68 }

 

posted @ 2015-07-12 20:48  罗茜  阅读(307)  评论(0编辑  收藏  举报