• uva 10766 Organising the Organisation 生成树计数


    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1707

    题意:给出n, m, k。表示n个点,其中m条边不能直接连通,求生成树个数。

    思路:

    参考周冬的《生成树的计数及其应用》。就是Matrix-Tree定理的应用。

    对于一个无向图G,它的生成树个数等于其Kirchhoff矩阵任何一个n-1阶主子式的行列式的绝对值。

    所谓n-1阶主子式,就是对于任意一个r,将C的第r行和第r列同时删去后的新矩阵,用Cr表示。

    Kirchhoff矩阵:对于无向图G,它的Kirchhoff矩阵C定义为它的度数矩阵D减去它的邻接矩阵A。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 int n, m, k;
     6 #define maxn 55
     7 long long A[maxn][maxn];
     8 long long BB[maxn][maxn];
     9 void determinant()
    10 {
    11     long long ans = 1;
    12     int cnt = 0;
    13     for(int i = 1; i <= n; i++)
    14     {
    15         for(int j = i+1; j <= n; j++)
    16         {
    17             int x = i, y = j;
    18             while(BB[y][i])
    19             {
    20                 long long t = BB[x][i] / BB[y][i];
    21                 for(int k = 1; k <= n; k++)
    22                 {
    23                     BB[x][k] = BB[x][k] - BB[y][k]*t;
    24                 }
    25                 swap(x, y);
    26             }
    27             if(x != i)
    28             {
    29                 for(int k = 1; k <= n; k++) swap(BB[x][k], BB[y][k]);
    30                 cnt ^= 1;
    31             }
    32         }
    33         if(BB[i][i] == 0) 
    34         {
    35             ans = 0; break;
    36         }
    37         else ans = ans * BB[i][i];
    38     }
    39     if(cnt) printf("%lld
    ", -ans);
    40     else printf("%lld
    ", ans);
    41     
    42 }
    43 int main() 
    44 {
    45    // freopen("in.txt", "r", stdin);
    46     while(~scanf("%d%d%d", &n, &m, &k))
    47     {
    48         memset(A, 0, sizeof(A));
    49         memset(BB, 0, sizeof(BB));
    50         
    51         for(int i = 1; i <= m; i++)
    52         {
    53             long long a, b; 
    54             scanf("%lld%lld", &a, &b);
    55             A[a][b] = A[b][a] = 1;
    56         }
    57         for(int i = 1; i <= n; i++)
    58         {
    59             for(int j = 1; j <= n; j++)
    60             {
    61                 if(i != j && !A[i][j])
    62                 {
    63                     BB[i][i]++;
    64                     BB[i][j] = -1;
    65                 }
    66             }
    67         }
    68        
    69        n = n-1; 
    70        determinant();
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    303. Range Sum Query
    【Leetcode】292. Nim Game
    【c++】函数默认参数
    [err]default argument given for parameter 3 of '***'
    [err]multiple definition of `***'
    【leetcode】290. Word Pattern
    【leetcode】283. Move Zeroes
    【leetcode】278. First Bad Version
    【leetcode】268. Missing Number
    【leetcode】263. Ugly Number
  • 原文地址:https://www.cnblogs.com/titicia/p/5297762.html
Copyright © 2020-2023  润新知