uva 10766 Organising the Organisation 生成树计数
Posted 下周LGD该赢了吧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n", -ans); 40 else printf("%lld\n", 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 }
以上是关于uva 10766 Organising the Organisation 生成树计数的主要内容,如果未能解决你的问题,请参考以下文章
uva 10766 Organising the Organisation 生成树计数