摘自大牛的见解

生成树

生成树(spanning-tree)是图论里面一个重要的概念。

一个无向图的所有边构成的集合称为这个无向图的边集,一个构成树的边集的子集,就成为这个无向图的生成树。 如果只是要求一棵生成树或者是要求边总权值最小的生成树,有很多经典的算法,比如Prim与Kruscal算法。 然而如果要求一个无向图的生成树数量,就不是一个那么简单的任务了。

Matrix-Tree定理

以下引用自国家集训队2008论文集

Matrix-Tree定理是解决生成树计数问题最有力的武器之一。它首先于1847年被Kirchhoff证明。在介绍定理之前,我们首先明确几个概念:

1、 G的度数矩阵D[G]是一个nn的矩阵,并且满足:当i≠j时,dij=0;当i=j时,dij等于vi的度数。 2、 G的邻接矩阵A[G]也是一个nn的矩阵, 并且满足:如果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]表示。

The Matrix Revolutions(ICPC Regionals 2014 :: Asia - Shanghai Problem A)

给定一个无向图,每条边上有黑色或者白色,求黑色边数不超过K的生成树数量对10^9+7取模。 点数不超过50。

Matrix-Tree定理可以求出一个无向图的生成树数量,但这个问题似乎不能直接用Matrix-Tree定理解决,我们换个思路,如果把度数矩阵与邻接矩阵中的1换成代表颜色的字母代数x和y。这样得到的行列式就有x和y这两个未知元,此时行列式得到的值就是一个关于x与y的多项式。而且可以发现xayb的系数就是含有a条x边以及b条y边的生成树数量。

由于一个生成树边的数量等于点的数量-1,意味着得到的多项式满足a+b+1=点数。也就是说可以让y=1,这样就可以少一个变元,简化接下来的运算。

暴力解一个行列式需要枚举所有全排列的情况,时间复杂度极高。然而可以使用高斯消元来对行列式进行初等变换成一个上三角矩阵,这样只需要O(n3)的时间复杂度来求一个行列式对一个质数的取模,n为行列式的阶数。

然而这回这个问题里面有x这个变元,意味着我们无法进行高斯消元。但是知道得到的值是关于x的n阶多项式,可以考虑插值,把这个多项式的系数都计算出来,如果我们得到了所有系数,这个问题就迎刃而解了。

需要对一个n阶多项式插值,意味着至少需要知道n个这个多项式的取值。所以将x=0到n−1代入矩阵,分别解出对应的行列式,就能得到这些取值,时间复杂度为O(n4)。

最后一步就是多项式插值,可以采用高斯消元或者拉格朗日插值法。 如果用高斯消元,系数矩阵是一个0到n−1的范德蒙矩阵,它的逆矩阵可以直接计算出来。 如果采用拉格朗日插值,需要构造出n个多项式,满足当x=i时值为1,x≠i时值为0。对应取值的行向量与多项式构成的列向量做点积,就能得到这个行列式。

得到行列式之后,我们知道xi的系数就是有i条x边的生成树数量,所以只需将不超过K的系数之和计算出来就是答案。

时间: 2024-08-06 19:50:48

摘自大牛的见解的相关文章

JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编程作为自己职业生涯的起点.如何学好编程?如何成为优秀的程序员?如何规划好程序员这个职业?是许多年轻人关注的问题.在Infoworld最近做的一次调查中,邀请到了JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Spring Framework创建者Rod

Javascript模块化编程(二):AMD规范

作者: 阮一峰 日期: 2012年10月30日 这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块. (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块. 但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写法,岂不是乱了套!考虑到Javascript模块现在还没有官方规范,这一点就更重要了. 目前,通行的Javascript模块规范共有两种

AMD CMD 和 CommonJS

JS中的模块规范(CommonJS,AMD,CMD),如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已. 现在就看看吧,这些规范到底是啥东西,干嘛的.本文包括这三个规范的来源及对应的产物的原理. 一.CommonJS 1.一开始大家都认为JS是辣鸡,没什么用,官方定义的API只能构建基于浏览器的应用程序,逗我呢,这太狭隘了吧(用了个高端词,嘎嘎),CommonJS就按耐不住了,CommonJS API定义很多普通应用

对程序员的职业建议

对程序员的职业建议 软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编程作为自己职业生涯的起点.如何学好编程?如何成为优秀的程序员?如何规划好程序员这个职业?是许多年轻人关注的问题.在Infoworld最近做的一次调查中,邀请到了JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Spring Frame

js标签放在html的什么位置比较好

推荐的是js的script标签放在body的末尾,</body>标签之前,包含在body内! <body> <!--其它Html标签--> <script>js 代码/js 引用</script> </body> 这样写的好处: 1.避免因为加载(下载)脚本或脚本运行过慢,阻塞页面. 2.防止脚本运行时,页面未加载完成,造成script要操作的DOM结点没有加载完成而出错. 知乎大牛的见解:为什么把 Script 标签放在 body

20150226 IMX257 总线设备驱动模型编程之平台总线设备platform

20150226 IMX257 总线设备驱动模型编程之平台总线设备platform 2015-02-26 李海沿 前面我们实现了总线设备驱动模型,下面我们来了解一下平台总线,平台设备驱动 分为平台设备和平台驱动两种,和前面所说的设备驱动差不多 platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为platform_device. 一.平台设备介绍 1. p

技术大牛告诉你,如何系统有效的学习软件开发?

有些人一出生就是为电脑技术而活的,充满着浓厚的兴趣.特别对编程开发对电脑技术有自己的一些向往. 而往往有时总是依靠搜索引擎进行学习,东看一点西看一点,没有系统的学习完一整套思想逻辑. 自己也可能有所成就,但是每当进行进修的时候就会发现,自己的不足,学习其他的东西很费劲.那我们究竟应该如何系统有效的学习一门编程语言呢? 我也不是什么大神,至今学习C#语言三年,期间也学习java android python等其他语言.算是对学习一门编程语言有自己的一些小见解.希望能帮助正在准备学习一门新语言的你.

资深大牛推荐学习路线建议

一位资深程序员大牛给予Java初学者的学习路线建议 java学习这一部分其实也算是今天的重点,这一部分用来回答很多群里的朋友所问过的问题,那就是我你是如何学习Java的,能不能给点建议?今天我是打算来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容甚至是一些书籍.这一部分的内容,同样适用于一些希望转行到Java的同学. 在大家看之前,我要先声明两点.1.由于我本人是Java后端开发出身,因此所推荐的学习内容是Java Web和Java后端开发的路线,非Java Web和J

膜拜acm大牛 虽然我不会这题,但是AC还是没有问题的~(转自hzwer)

wywcgs: 亦称Lord Wu,俗名吴垠,2009级厦门大学智能科学与技术学院研究生,本科就读于哈尔滨工业大学.因其深厚的算法功底与独到的思维方式,被尊为“吴教主”,至今声威犹存. 2006年起参加ACM/ICPC竞赛,获得分别获得上海.西安.长春三枚区域赛银牌. 2008年获得GCJ-BeiJing Onsite参赛资格,并在比赛中表现优异,获得Final资格,后因个人原因,推掉了总决赛资格,并忙于为各赛区出题. 2010年复出比赛,在福建省举办的全国邀请赛中力压群牛,获得赛区金牌,给同场