spoj 104 Highways(Matrix-tree定理)

spoj 104 Highways

生成树计数,matrix-tree定理的应用。

Matrix-tree定理:

D为无向图G的度数矩阵(D[i][i]是i的度数,其他的为0),A为G的邻接矩阵(若u,v之间存在边,A[u][v]=A[v][u]=1),C=D-A。

对于一个无向图G,它的生成树个数等于其Kirchhoff矩阵任何一个n-1阶主子式的行列式的绝对值。 所谓n-1阶主子式,就是对于任意一个r,将C的第r行和第r列同表示时删去后的新矩阵,表示为Cr。

求行列式的值:

把矩阵用高斯消元消成上三角矩阵,对角线的积就是行列式的值。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6
 7 using namespace std;
 8
 9 const double eps = 1e-15;
10
11 double c[20][20];
12 int T,n,m;
13
14 double Gauss() {
15     for (int k=1; k<=n; ++k) {
16         int r = k;
17         for (int i=k+1; i<=n; ++i)
18             if (fabs(c[i][k]) > fabs(c[r][k])) r = i;
19         if (r!=k) for (int j=1; j<=n; ++j) swap(c[k][j],c[r][j]);
20         for (int i=k+1; i<=n; ++i)
21             if (fabs(c[i][k]) > eps) {
22                 double t = c[i][k] / c[k][k];
23                 for (int j=k; j<=n; ++j) c[i][j] -= t*c[k][j];
24             }
25     }
26     double ans = 1.0;
27     for (int i=1; i<=n; ++i) ans = ans*c[i][i]; //矩阵的对角线乘积
28     return (ans > 0) ? ans : -ans;//取绝对值
29 }
30
31 int main() {
32     scanf("%d",&T);
33     while (T--) {
34         memset(c,0,sizeof(c));
35         scanf("%d%d",&n,&m);
36         for (int u,v,i=1; i<=m; ++i) {
37             scanf("%d%d",&u,&v);
38             c[u][v] = c[v][u] = -1;//边
39             c[u][u] ++;c[v][v] ++;//度数
40         }
41         n--; // 去掉最后一行最后一列
42         double ans = Gauss(); //高斯消元
43         printf("%.0lf\n",ans+eps);
44     }
45     return 0;
46 }

原文地址:https://www.cnblogs.com/mjtcn/p/8502826.html

时间: 2024-10-10 05:03:09

spoj 104 Highways(Matrix-tree定理)的相关文章

@算法 - [email&#160;protected] matrix - tree 定理(矩阵树定理)

目录 @0 - 参考资料@ @0.5 - 你所需要了解的线性代数知识@ @1 - 定理主体@ @证明 part - [email protected] @证明 part - [email protected] @证明 part - [email protected] @证明 part - 4@ @2 - 一些简单的推广@ @3 - 例题与应用@ @0 - 参考资料@ MoebiusMeow 的讲解(超喜欢这个博主的!) 网上找的另外一篇讲解 @0.5 - 你所需要了解的线性代数知识@ 什么是矩阵

HDU 4305 Lightning Matrix Tree定理

题目链接:https://vjudge.net/problem/HDU-4305 解法:首先是根据两点的距离不大于R,而且中间没有点建立一个图.之后就是求生成树计数了. Matrix-Tree定理(Kirchhoff矩阵-树定理).Matrix-Tree定理是解决生成树计数问题最有力的武器之一.它首先于1847年被Kirchhoff证明.在介绍定理之前,我们首先明确几个概念: 1.G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0:当i=j时,dij等于vi的度数. 2.G

SPOJ 104 Highways 最小生成树计数

题目链接:点击打开链接 题意: 给定n个点m条边的无向图,问最小生成树有几个. 思路: 模版 #pragma comment(linker, "/STACK:1024000000,1024000000") #include<bits/stdc++.h> template <class T> inline bool rd(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; while(c!

矩阵树定理(Matrix Tree)学习笔记

如果不谈证明,稍微有点线代基础的人都可以在两分钟内学完所有相关内容.. 行列式随便找本线代书看一下基本性质就好了. 学习资源: https://www.cnblogs.com/candy99/p/6420935.html http://blog.csdn.net/Marco_L_T/article/details/72888138 首先是行列式对几个性质(基本上都是用数学归纳法证): 1.交换两行(列),行列式取相反数 2.由1.得若存在两行(列)完全相同则行列式为0 3.上(下)三角行列式即主

BZOJ 1002 + SPOJ 104 基尔霍夫矩阵 + 一个递推式。

BZOJ 1002 高精度 + 递推 f[1] = 1; f[2] = 5; f[i] = f[i - 1] * 3 - f[i - 2] + 2; SPOJ 104 裸 + 不用Mod 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <iostream> 6 7 using namespace std;

最小生成树计数(matrix tree矩阵树定理)

Matrix-Tree 定理是解决生成树计数问题最有力的武器之一.它首先于 1847 年被Kirchhoff 证明. 在介绍定理之前, 我们首先明确几个概念: 1. G 的度数矩阵 D[G]是一个 n*n 的矩阵, 并且满足: 当 i≠j 时,dij=0:当 i=j时, dij 等于 vi 的度数. 2. G 的邻接矩阵 A[G]也是一个 n*n 的矩阵, 并且满足: 如果 vi. vj 之间有边直接相连,则 aij=1,否则为 0. 我们定义 G 的 Kirchhoff 矩阵(也称为拉普拉斯算

【算法】Matrix - Tree 矩阵树定理 &amp; 题目总结

最近集中学习了一下矩阵树定理,自己其实还是没有太明白原理(证明)类的东西,但想在这里总结一下应用中的一些细节,矩阵树定理的一些引申等等. 首先,矩阵树定理用于求解一个图上的生成树个数.实现方式是:\(A\)为邻接矩阵,\(D\)为度数矩阵,则基尔霍夫(Kirchhoff)矩阵即为:\(K = D - A\).具体实现中,记 \(a\) 为Kirchhoff矩阵,则若存在 \(E(u, v)\) ,则\(a[u][u] ++, a[v][v] ++, a[u][v] --, a[v][u] --\

SPOJ - HIGH Highways(矩阵树定理)

https://vjudge.net/problem/SPOJ-HIGH 题意: 给n个点m条边,求生成树个数. 思路: 矩阵树裸题. 具体的话可以看一下周冬的论文<生成树的计数及其应用>. 简单说一下,$A[ ][ ]$为邻接矩阵,有边为1(其实也就是边的个数,有重边时要注意),无边为0.$D[ ][ ]$为度数矩阵,$i=j$时为1,否则为0. $C[ ][ ]$为关联矩阵,$C[ ][ ]=D[ ][ ]-A[ ][ ]$. 最后解任意n-1阶的主子式即可. 1 #include<

[SPOJ]Query on a tree(树链剖分,线段树)

题目链接:http://www.spoj.com/problems/QTREE/en/ 照着集训队论文敲的…万幸树剖部分没写错… 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream>