zoukankan      html  css  js  c++  java
  • 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
    ", (double)MTree (n - 1));
    66     }
    67     return 0;
    68 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    ADO.NET Entity Framework之ObjectQuery
    高效byte[]和string互转的方法
    异步邮件发送
    ADO.NET Entity Framework之ObjectContext
    【转】Memcache and Mongodb
    一周工作总结一次SQL优化记录
    Ubuntu下有关Java和数据库的一些工作记录(一)
    自定义函数,替换字符串中指定位置的字符
    一次优化记录
    对比shrink和move
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4641502.html
Copyright © 2011-2022 走看看