信息学竞赛中,有关生成树的最优化问题如最小生成树等是我们经常遇到的,而对生成树的计数及其相关问题则少有涉及。事实上,生成树的计数是十分有意义的,在许多方面都有着广泛的应用。本文从一道信息学竞赛中出现的例题谈起,首先介绍了一种指数级的动态规划算法,然后介绍了行列式的基本概念、性质,并在此基础上引入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(矩阵树)定理相关推荐

  1. [BZOJ4596][Shoi2016]黑暗前的幻想乡-Matrix Tree 矩阵树定理

    黑暗前的幻想乡 Description 四年一度的幻想乡大选开始了,最近幻想乡最大的问题是很多来历不明的妖怪涌入了幻想乡,扰乱了幻想乡昔日的秩序.但是幻想乡的建制派妖怪(人类)博丽灵梦和八云紫等人整日 ...

  2. 【BZOJ1016】【Luogu P4208】 [JSOI2008]最小生成树计数 最小生成树,矩阵树定理

    蛮不错的一道题,遗憾就遗憾在数据范围会导致暴力轻松跑过. 最小生成树的两个性质: 不同的最小生成树,相同权值使用的边数一定相同. 不同的最小生成树,将其都去掉同一个权值的所有边,其连通性一致. 这样我 ...

  3. 行列式入门与矩阵树定理完整证明

    文章目录 前置技能 行列式 定义 性质 拉普拉斯展开 线性性 可乘性 可加性 不重性 可倍加性 转置不变性 可交换性 行可交换性 列可交换性 优化行列式的计算 矩阵树定理 前置定义 一些引理 转置引理 ...

  4. [XSY]Tree Ext(矩阵树定理,拉格朗日插值,最小生成树,二分)

    Tree Ext 这道题相当于把3道题合了起来. 要求修复的边中恰好有 k 条白边: 五颜六色的幻想乡(附拉格朗日插值法求多项式系数 ) + bzoj2654 tree(WQS二分 新科技get) 是 ...

  5. BZOJ1016 || 洛谷P4208 [JSOI2008]最小生成树计数【矩阵树定理】

    时空限制 1000ms / 128MB 题目描述 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则 ...

  6. 最小生成树、矩阵树定理、Prufer序列总结

    Kruskal算法 按边权排序,从小到大合并不在同一集合两点即可 Prim算法 每次加入一个到当前已选点集最近的点 P2619 [国家集训队]Tree I 考虑二分,每次给白边加上一个mid,通过这种 ...

  7. 矩阵树定理2020HDU多校第6场j-Expectation[位运算+期望]

    矩阵树定理 用于求解图上面生成树的个数,生成树的个数等于基尔霍夫矩阵的任何一个N-1阶主子式的行列式的绝对值 矩阵树模板 struct Matrix_Tree {ll a[N][N];Matrix_T ...

  8. 【学习笔记】矩阵树定理(Matrix-Tree)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 一.矩阵树定理 二.常用定理 三.例题 1. Luogu P6178 [模板]Matrix-Tr ...

  9. 图论数学:矩阵树定理

    运用矩阵树定理进行生成树计数 给定一个n个点m条边的无向图,问生成树有多少种可能 直接套用矩阵树定理计算即可 矩阵树定理的描述如下: 首先读入无向图的邻接矩阵,u-v G[u][v]++ G[v][u ...

最新文章

  1. 【C++】用指针做函数参数
  2. 深入浅出LSTM神经网络
  3. 常见数字IC设计、FPGA工程师面试题
  4. 信阳农林技术学院经纬度_信阳农林学院全景-360度,720度,高清全景地图-expoon网展...
  5. erp服务器型号,erp服务器硬件配置
  6. Quartz源码总结
  7. Java学习从入门到精通[转]
  8. 机器学习11/100天-KNN实践
  9. grpc java 泛型_关于使用GRPC遇到的BUG-Go语言中文社区
  10. 从技术角度看人人网,互联网营销
  11. Excel为图表添加趋势线和公式
  12. SegNet算法详解
  13. nba2k20手游修改器服务器已到,NBA2K20手机版万能修改器
  14. 迷你云服务器怎么开,迷你世界迷你云服怎么开_迷你世界迷你云服打开方法_玩游戏网...
  15. Asp.Net MVC4.0 官方教程 入门指南之六--查看Edit方法和Edit视图
  16. 使用webrtc开发直播系统源码,开发音视频语聊房
  17. 使用B站API:http://api.bilibili.com/x/space/upstat?mid=2026561407获取播放量、点赞量的返回报文中data数据缺失问题排查(已解决)
  18. 哪种耳机音质好又便宜?高性价比蓝牙耳机推荐
  19. 美颜SDK的动态贴纸有哪些妙用?
  20. 大数据图书分享-Python数据可视化实战课程

热门文章

  1. Eclipse中自定义注释
  2. 使用HttpSessionBindingListener方法
  3. float、double(浮点数)区别还有和decimal(定点数)的比较
  4. Selector SelectionKey
  5. Docker部署ElasticSearch7.11.1并挂载+配置X-Pack设置帐号密码+Kibana7.11.1+IK插件
  6. UNIX再学习 -- 死磕内存管理
  7. 百度浏览器支持html5,百度手机浏览器完美驾驭HTML5
  8. js如何同时打开多个信息窗口 高德地图_高德地图显示单个窗体和显示多个窗体的方法...
  9. LSTM implementation explained
  10. Tensorflow学习