Kirchhoff 矩阵法是根据Matrix-Tree定理来的,本人太菜,没有那个心力去看证明了,知道是用就可以了

作用:

给定一个n个点m条边的无向图,求出这个图的生成树的总数。

Matrix-Tree定理(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 矩阵(也称为拉普拉斯算⼦)C[G]为 C[G]=D[G]-A[G],则Matrix-Tree 定理可以描述为:G 的所有不同的⽣成树的个数等于其 Kirchhoff 矩阵 C[G]任何⼀个 n-1 阶主⼦式的⾏列式的绝对值。所谓 n-1 阶主⼦式,就是对于r(1≤r≤n),将 C[G]的第 r ⾏、第 r 列同时去掉后得到的新矩阵,⽤ Cr[G]表示。

矩阵树方法实现:
实现方法很简单,第一步是构建拉氏矩阵,很简单。难点在于实现求行列式的值。我这里采用矩阵初等变换将矩阵转化为上三角矩阵,这样行列式的值就等于主对角元素乘积。我实现了打印拉氏矩阵C和输出图生成树个数这两个方法,主体程序如下:

#include<bits/stdc++.h>using namespace std;class spanningTreeNum {private:int V = 0;  // 顶点数vector<vector<int> > c; // 拉式矩阵c=d-A
public:spanningTreeNum(int V){this->V = V;c = vector<vector<int> >(V, vector<int>(V, 0));  //初始化二维矩阵c为0}void addEdge(int u, int v);  // u和v之间加一条边int getTreeNum();int det(vector<vector<float> > A);  // 求行列式A的值void showC();
};void spanningTreeNum::addEdge(int u, int v) {c[u][u]++;  // 顶点度数加一c[v][v]++;c[u][v] = -1;  // 表示顶点u、v之间有一条边,因为c=d-A,所以为-1c[v][u] = -1;
}int spanningTreeNum::det(vector<vector<float> > A) {/** 思路是将利用初等变换A转化为上三角矩阵,这样对角线元素乘积即为行列式值*/float res = 1;int iter = 0;  // 记录交换次数for (int i = 0; i < A.size(); ++i) {  //该for循环内的逻辑是将矩阵转化为上三角矩阵if(A[i][i]==0) {for (int j = i; j < A.size(); ++j) {if(A[j][i]!=0) {swap(A[i], A[j]);iter++;}}}for (int j = i+1; j < A.size(); ++j) {float temp = -A[j][i]/A[i][i];for (int k = 0; k < A[j].size(); ++k) {A[j][k] = A[i][k]*temp+A[j][k];}}}for (int i = 0; i < A.size(); ++i) {res *= A[i][i];}if(iter%2==1) res = -res;return (int)res;
}
int spanningTreeNum::getTreeNum() {// 求余子式vector<vector<float > > temp(V-1, vector<float >(V-1, 0));for (int i = 1; i < V; ++i) {for (int j = 1; j < V; ++j) {temp[i-1][j-1] = c[i][j];}}return det(temp);
}void spanningTreeNum::showC() {for (int i = 0; i < c.size(); ++i) {for (int j = 0; j < c[i].size(); ++j) {printf("%3d ", c[i][j]);}cout << endl;}
}int main()
{spanningTreeNum G(4);G.addEdge(0, 1);G.addEdge(0, 2);G.addEdge(1, 2);G.addEdge(2, 3);cout << "拉氏矩阵为:" << endl;G.showC();  //打印拉式矩阵Ccout << "生成树个数为:" << G.getTreeNum() << endl; // 打印生成树个数return 0;
}

运行结果:

无向图生成树计数 -- Kirchhoff 矩阵法模板相关推荐

  1. 【矩阵乘法】生成树计数(luogu 2109/NOI 2007)

    生成树计数 luogu 2109 题目大意 有n个排成一列的点,把距离不超过k的点之间连边,问这个图的生成树个数 输入样例 3 5 输出样例 75 样例说明 样例对应的图如下: 数据范围 解题思路 因 ...

  2. Matrix-Tree (生成树计数)

    生成数计数 对于一个无向简单图,nnn个点和n−1n-1n−1条边构成一个生成树,生成树计数就是求这个无向图中一共有几种不同的生成树(任意两边不同) 度矩阵 n×nn × nn×n 的矩阵,统计每个点 ...

  3. 生成树计数Matrix-Tree定理-数学

    https://www.cnblogs.com/zj75211/p/8039443.html 度数矩阵减去邻接矩阵 再求去掉一行一列的行列式 生成树计数问题: 对于一个有n个点的无向图,由图中n-1条 ...

  4. java tree degree_生成树计数-Matrix-Tree定理

    /* *算法引入: *给定一个无向图G,求它生成树的个数t(G); * *算法思想: *(1)G的度数矩阵D[G]是一个n*n的矩阵,并且满足:当i≠j时,dij=0;当i=j时,dij等于vi的度数 ...

  5. bzoj1002 生成树计数 找规律

    这道题第一眼是生成树计数,n是100,是可以用O(n^3)的求基尔霍夫矩阵的n-1阶的子矩阵的行列式求解的,但是题目中并没有说取模之类的话,就不好办了. 用高精度?有分数出现. 用辗转相除的思想,让它 ...

  6. 最短路径生成树计数+最短路径生成树

    最短路径生成树计数. 我们应该先明白什么是最短路径生成树,不会戳这里. 计数方法明显是要使用乘法原理计数,也就是说我们可以得出每一步的方案数再乘进答案中. 接下来考虑如何的出每一步的方案数,所谓方案数 ...

  7. 图论 —— 生成树 —— 生成树计数

    [概述] 给出一个由 n 个点和 m 条边构成的简单无向加权图,有时需要对生成树计数或对最小生成树计数. 当对生成树计数时,利用基尔霍夫矩阵的 Matrix-Tree 定理即可解决,而对最小生成树计数 ...

  8. HDU 4305 Lightning (高斯消元解kirchhoff矩阵+逆元)

    题意是:给一些坐标点,如果两点之间的距离小于R,并且两点之间没有其他点,则这两个点保持连通,这样构成了一个图.问这个图中生成树的个数. 因为数据量并不大,O(N^3)的建图没有问题. 建好图以后就可以 ...

  9. Ural 1627 Join(生成树计数)

    http://acm.timus.ru/problem.aspx?space=1&num=1627 生成树计数的题,直接用Matrix-Tree定理就可以解决问题了. 代码如下: View C ...

最新文章

  1. Android Studio 打开提示Invalid Gradle JDK configuration found错误
  2. CentOS+Nginx+Tomcat+Mysql+PHP 环境搭建及系统部署
  3. 007_html头部元素
  4. 如何编写第三方接口_Python接口测试之数据驱动
  5. Java类集框架 —— HashMap源码分析
  6. 137. 只出现一次的数字 II
  7. eclipse检测不到android的手机
  8. VCenter配置ESXI主机syslog日志收集
  9. IE下angularJS页面跳转的bug
  10. [转]ExtJS的使用方法汇总—配置和表格控件使用
  11. rsa加解密及加签验签
  12. 商城管理系统(前台+后台+管理员+用户+html+jsp)
  13. java连接数据库(sqlserver和mysql)
  14. Arcgis如何使用三调数据统计土地三大类
  15. 单项选择题标准化考试系统
  16. 菜鸟教程:Js数据类型
  17. Qt获取键盘按键ctrl和alt以及shift按键按下和松开
  18. LSL-- Flow Control
  19. 2023最新最全git安装教程,保姆级手把手式安装!!!
  20. 编译原理期末复习—第一章概论

热门文章

  1. 电脑上如何实现微信双开或者多开
  2. 利用Scrapy爬取豆瓣排名前250部电影封面
  3. 使用宏批量插入图片到Word表格
  4. 自定义生成公众号二维码,用于小票打印机使用
  5. 神经网络预测应力应变-单轴实验
  6. 音乐发烧友的珍藏超经典CD之一
  7. tree树形控件之循环遍历
  8. 【Telegram】开启允许权限让你的TG可以实现bot直接监控频道
  9. Iterm2保存服务器账密
  10. win10 鼠标指针