生成树的计数 Matrix-Tree(矩阵树)定理
信息学竞赛中,有关生成树的最优化问题如最小生成树等是我们经常遇到的,而对生成树的计数及其相关问题则少有涉及。事实上,生成树的计数是十分有意义的,在许多方面都有着广泛的应用。本文从一道信息学竞赛中出现的例题谈起,首先介绍了一种指数级的动态规划算法,然后介绍了行列式的基本概念、性质,并在此基础上引入Matrix-Tree定理,同时通过与一道数学问题的对比,揭示了该定理所包含的数学思想。最后通过几道例题介绍了生成树的计数在信息学竞赛中的应用,并进行总结。
生成树的计数 Matrix-Tree定理
问题的提出
[例一]高速公路(SPOJ 104 Highways)
一个有n座城市的组成国家,城市1至n编号,其中一些城市之间可以修建高速公路。现在,需要有选择的修建一些高速公路,从而组成一个交通网络。你的任务是计算有多少种方案,使得任意两座城市之间恰好只有一条路径?
数据规模:1≤n≤12。
[分析]
我们可以将问题转化到成图论模型。因为任意两点之间恰好只有一条路径,所以我们知道最后得到的是原图的一颗生成树。因此,我们的问题就变成了,给定一个无向图G,求它生成树的个数t(G)。这应该怎么做呢?
经过分析,我们可以得到一个时间复杂度为O(3n*n2)的动态规划算法,因为原题的规模较小,可以满足要求。但是,当n再大一些就不行了,有没有更优秀的算法呢?答案是肯定的。在介绍算法之前,首先让我们来学习一些基本的预备知识。
新的方法介绍
下面我们介绍一种新的方法——Matrix-Tree定理(Kirchhoff矩阵-树定理)。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矩阵(也称为拉普拉斯算子)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]表示。
生成树计数
算法步骤:
1、 构建拉普拉斯矩阵
Matrix[i][j] =
degree(i) , i==j
-1,i-j有边
0,其他情况
2、 去掉第r行,第r列(r任意)
3、 计算矩阵的行列式
论文 周冬 《生成树计数应用》
#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 105;
const int maxm = 100005;
const int INF = 1e9;
int degree[maxn];
ll g[maxn][maxn];
int n, m; ll det(ll a[][maxn], int n)
{ ll ret = 1; for(int i=1; i<n; ++i){ for(int j=i+1; j<n; ++j){ while(a[j][i]){ ll t = a[i][i]/a[j][i]; for(int k=i; k<n; ++k){ a[i][k] = (a[i][k]-a[j][k]*t); } for(int k=i; k<n; ++k){ swap(a[i][k], a[j][k]); } ret = -ret; } } if(a[i][i]==0){ return 0; } ret = ret*a[i][i]; } if(ret<0){ ret = -ret; } return ret;
} void solve()
{ int u, v; memset(degree, 0, sizeof degree ); memset(g, 0, sizeof g ); scanf("%d%d", &n, &m); while(m--){ scanf("%d%d", &u, &v); u--,v--; g[u][v] = g[v][u] = -1; degree[u]++; degree[v]++; } for(int i=0; i<n; ++i){ g[i][i] = degree[i]; } printf("%lld\n", det(g, n));
} int main()
{ int t; scanf("%d", &t); while(t--){ solve(); } return 0;
}
转载于:https://www.cnblogs.com/tham/p/6827125.html
生成树的计数 Matrix-Tree(矩阵树)定理相关推荐
- [BZOJ4596][Shoi2016]黑暗前的幻想乡-Matrix Tree 矩阵树定理
黑暗前的幻想乡 Description 四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖怪涌入了幻想乡,扰乱了幻想乡昔日的秩序.但是幻想乡的建制派妖怪(人类)博丽灵梦和八云紫等人整日 ...
- 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理
蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...
- 行列式入门与矩阵树定理完整证明
文章目录 前置技能 行列式 定义 性质 拉普拉斯展开 线性性 可乘性 可加性 不重性 可倍加性 转置不变性 可交换性 行可交换性 列可交换性 优化行列式的计算 矩阵树定理 前置定义 一些引理 转置引理 ...
- [XSY]Tree Ext(矩阵树定理,拉格朗日插值,最小生成树,二分)
Tree Ext 这道题相当于把3道题合了起来. 要求修复的边中恰好有 k 条白边: 五颜六色的幻想乡(附拉格朗日插值法求多项式系数 ) + bzoj2654 tree(WQS二分 新科技get) 是 ...
- BZOJ1016 || 洛谷P4208 [JSOI2008]最小生成树计数【矩阵树定理】
时空限制 1000ms / 128MB 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则 ...
- 最小生成树、矩阵树定理、Prufer序列总结
Kruskal算法 按边权排序,从小到大合并不在同一集合两点即可 Prim算法 每次加入一个到当前已选点集最近的点 P2619 [国家集训队]Tree I 考虑二分,每次给白边加上一个mid,通过这种 ...
- 矩阵树定理2020HDU多校第6场j-Expectation[位运算+期望]
矩阵树定理 用于求解图上面生成树的个数,生成树的个数等于基尔霍夫矩阵的任何一个N-1阶主子式的行列式的绝对值 矩阵树模板 struct Matrix_Tree {ll a[N][N];Matrix_T ...
- 【学习笔记】矩阵树定理(Matrix-Tree)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 一.矩阵树定理 二.常用定理 三.例题 1. Luogu P6178 [模板]Matrix-Tr ...
- 图论数学:矩阵树定理
运用矩阵树定理进行生成树计数 给定一个n个点m条边的无向图,问生成树有多少种可能 直接套用矩阵树定理计算即可 矩阵树定理的描述如下: 首先读入无向图的邻接矩阵,u-v G[u][v]++ G[v][u ...
最新文章
- 【C++】用指针做函数参数
- 深入浅出LSTM神经网络
- 常见数字IC设计、FPGA工程师面试题
- 信阳农林技术学院经纬度_信阳农林学院全景-360度,720度,高清全景地图-expoon网展...
- erp服务器型号,erp服务器硬件配置
- Quartz源码总结
- Java学习从入门到精通[转]
- 机器学习11/100天-KNN实践
- grpc java 泛型_关于使用GRPC遇到的BUG-Go语言中文社区
- 从技术角度看人人网,互联网营销
- Excel为图表添加趋势线和公式
- SegNet算法详解
- nba2k20手游修改器服务器已到,NBA2K20手机版万能修改器
- 迷你云服务器怎么开,迷你世界迷你云服怎么开_迷你世界迷你云服打开方法_玩游戏网...
- Asp.Net MVC4.0 官方教程 入门指南之六--查看Edit方法和Edit视图
- 使用webrtc开发直播系统源码,开发音视频语聊房
- 使用B站API:http://api.bilibili.com/x/space/upstat?mid=2026561407获取播放量、点赞量的返回报文中data数据缺失问题排查(已解决)
- 哪种耳机音质好又便宜?高性价比蓝牙耳机推荐
- 美颜SDK的动态贴纸有哪些妙用?
- 大数据图书分享-Python数据可视化实战课程
热门文章
- Eclipse中自定义注释
- 使用HttpSessionBindingListener方法
- float、double(浮点数)区别还有和decimal(定点数)的比较
- Selector SelectionKey
- Docker部署ElasticSearch7.11.1并挂载+配置X-Pack设置帐号密码+Kibana7.11.1+IK插件
- UNIX再学习 -- 死磕内存管理
- 百度浏览器支持html5,百度手机浏览器完美驾驭HTML5
- js如何同时打开多个信息窗口 高德地图_高德地图显示单个窗体和显示多个窗体的方法...
- LSTM implementation explained
- Tensorflow学习