不来也不去的一只失忆蝴蝶

曾迷途才怕追不上满街赶路人

生成树计数问题——矩阵树定理及其证明

生成树计数问题

给一副n个节点的无向图G,求一个包含n-1条边的边集使得边集的边构成一颗树,问这样的边集的数量。

矩阵树定理

以下我们都不对重边与自环进行讨论。
实际上,即使有重边矩阵树定理仍然是正确的。
先定义度数矩阵D,是一个n*n的矩阵。
Di,i=节点i的度数,对于i不等于j,Di,j=0。
再定义邻接矩阵A,也是一个n*n的矩阵。
i与j有边相连就有Ai,j=1否则Ai,j=0。
最后定义基尔霍夫矩阵C=D-A。
那么,Ci,i=i的度数,对于i不等于j,若i与j间有边相连则Ci,j=-1否则Ci,j=0。
为了方便一些萌新,讲讲行列式吧。
我们都知道一个n*n矩阵a的行列式的定义:
bn(1)bΠni=1ai,bi
这个记作det(a),或者说|a|。
行列式有一些性质:
1、|A|=|AT|
2、|AB|=|A||B|
我们知道矩阵乘法后位置(i,j)由A的第i行与B的第j列点积而来,即A的第i行与BT的第j行点积,容易得到|AB|=|A||BT|=|A||B|
3、两个矩阵都是n*n的,除了第一行完全相同,那么它们的行列式之和等于将它们第一行相加其余不变的新矩阵的行列式。
这个非常好懂。
同样根据性质能得到一些推论:
1、将A任意两行或两列交换得到新矩阵B,则|B|=-|A|。
根据定义看,容易证明交换后任意排列的逆序对个数改变了1。
而这样的话,重排对角线因为每次一定要同时交换行列,所以行列式是不变的。
2、将A任意一行同时乘上x得到新矩阵B,则|B|=x|A|。
易证
3、将A任意一行乘以同一个数加到另一行上,得到新矩阵B,则|B|=|A|
根据行列式性质3我们可以很容易脑补出来。
我们把它拆出来变成两个矩阵行列式之和。
其中有一个矩阵的两行相同,容易得到其行列式为0。
因为这两行一个选i一个选j与另一种方案一个选j一个选i显然正负抵消。
这三个推论让我们可以使用高斯消元求解行列式。
4、每行每列和均为0的矩阵行列式为0。
高斯消元过程中这一性质仍然存在。
最后消出来,最后一行前n-1一定为0,又因和为0,所以最后一项也是0,那么行列式即为0。

来定义一个矩阵A的余子式Mi,j表示A去掉第i行与第j列后的行列式。
矩阵树定理:基尔霍夫矩阵C的任意余子式Mi,i就是图G的生成树个数。
接下来我们尝试证明吧。

先知道基尔霍夫矩阵的性质:
1、|C|=0
容易知道C的每行每列和均为0,那么根据推论4得出行列式也为0。
2、若图G不联通,则任意余子式Mi,i=0
我们进行重标号使联通的点在主对角线上连续。
因此同一个联通块对应了一个基尔霍夫矩阵(除了该联通块内部有边其余均为0)。
显然Mi,i是0,因为去掉任意第i行与第i列后,除i所在联通块的基尔霍夫矩阵外还有其他的基尔霍夫矩阵,而Mi,i等于所有这些矩阵行列式的积(这个易证),根据基尔霍夫矩阵性质1得证。
3、若图G是一颗树,则任意余子式Mi,i=1
不如我们尝试同时证明下面三个命题
A:若图G是一颗树,则其基尔霍夫矩阵C的任意余子式Mi,i=1。
B:若图G是一颗树,则将其基尔霍夫矩阵C的C1,1加上1后,得到新矩阵C’,|C’|=1。
C:若图G是一颗树,则将其基尔霍夫矩阵C的C1,1加上1后,得到新矩阵C’,C’的余子式M1,1=1。
我们使用归纳法同时证明A、B、C三个命题均是正确的。
首先三个命题在最小的规模时均为正确的,这是显然的。
如果B命题正确,A命题当然是正确的。
我们可以对C矩阵进行重编号,让属于同一颗子树的编号为连续一段区间(我们当然需要钦点一个根,编号为1),在主对角线上靠在一起。
既然是任意余子式Mi,i,我们不妨计算M1,1(任意的Mi,i只是说明谁被钦点为根)。去掉第一行第一列后,C显然被分成了很多个部分,每一个部分都是原本1的一颗子树,根据行列式的性质,M1,1应该等于这些矩阵的行列式的乘积。我们注意到每一部分的矩阵都是对应子树的基尔霍夫矩阵,根节点那加了1的结果(基尔霍夫矩阵等于度数矩阵-邻接矩阵,那么因为原本有一个根节点与其相连,所以度数那会多1个1)。
我们假设了B命题正确,那么M1,1等于一堆1相乘,结果也为1,A命题正确。
接下来我们证明,如果C命题正确,那么B命题也正确。如果B命题正确,那么C命题也正确。
先证如果C命题正确,那么B命题也正确。
同样是经典重编号,度数莫名多了1的那个就被我们钦点为根节点。
回到行列式最经典的定义,如果我们枚举的排列选择了(1,1),那么贡献为(1,1)的值乘上每个部分的行列式,因为假设了B命题正确,所以贡献为根节点度数+1。
如果选择的是(1,i)其中i>1,因为贡献不为0,那么i与1之间肯定有连边,我们知道每一个子树,例如编号在[l,r],每一行选择的必须是1或[l,r]内的,才能使贡献不为0。
可以发现,我们必须选择(i,1)。
(1,i)与(i,1)均为-1,且造成一个逆序对,.而中间的逆序对个数显然是偶数,因此此时对行列式的贡献应该是除i所在矩阵的行列式相乘再乘上i所在矩阵去除自己所在行列的余子式。因为逆序对还要取相反数。
那么因为C命题正确,一个i造成-1的贡献。
一共可选的合法i有根的度数个,所以行列式为1,B命题正确。
接下来证明如果B命题正确那么C命题正确。
这就很显然了嘛是不是。
所以ABC三个命题都是正确的!

接下来可以正式开始矩阵树定理的证明了!
我们来定义一个辅助矩阵B:
B是一个m*n的矩阵,m就是边数。
对于第i条边(u,v),Bi,u=1,Bi,v=-1。
其余均为0。
有一个结论那就是C=BTB
这个非常好证明,这里略去不证。
有一个Binet-Cauchy定理,非常难证,这里只给出结论不给出证明:
对于两个矩阵A与B,A是n*m的,B是m*n的,那么
|AB|=|s|=n|AsBs|
大概含义是,选取一个大小为n的子集,然后A矩阵只保留对应列,B矩阵只保留对应行,再做矩阵乘法和行列式,所有这样的子集得到贡献相加即可。
回到矩阵树定理。设Ai就表示矩阵A去掉第i行第i列后的子矩阵。
|Ci|=|BTiBi|=|s|=n1|BTisBis|
后面那个东西乘出来其实是原图选择了n-1条边后的基尔霍夫矩阵的余子式!
我们知道矩阵乘法是一行乘一列,一个矩阵转置再乘本身的话,可以看做一行乘一行!
容易得到
|Ci|=|s|=n1|Bis|2
接下来就很容易啦,我们需要证明后面那个东西为啥就是生成树个数呢?
我们相当于从边集里选出了n-1的边。
于是下面又有三种情况:
1、选出的边不连通,贡献为0。
这是根据基尔霍夫矩阵的性质2。
2、选出的边组成环,贡献为0。
有环的话把环靠在一起那么是退化矩阵行列式为0,因此贡献肯定为0啊。
2、选出的边组成树,贡献为1。
这是根据基尔霍夫矩阵的性质3。

那么只有选择是能构成树时有1的贡献。
所以矩阵树定理是正确的!
于是就完结撒花。

有趣的栗子

我们来常识用矩阵树定理解决一个简单问题。
求n个点组成的无根带标号树有多少个。
可以看做是无向完全图的生成树计数。
它的基尔霍夫矩阵主对角线都是n-1,其余全都是-1。
那余子式,也是一样,不过规模变成了(n-1)*(n-1)
现在求它的行列式
让第一行加上每行,第一行变成全都是1。
用第一行去加其余行,每个其余行除了在主对角线上是n全都变成0。
于是最后显然变成了一个上三角矩阵,行列式为主对角线元素相乘。
因此是nn2

阅读更多
版权声明:本文是蒟蒻写出来的,神犇转载也要说一声哦! https://blog.csdn.net/WerKeyTom_FTD/article/details/54914530
个人分类: 杂文 矩阵树定理
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭