Matrix tree定理用于连通图生成树计数,由于博主太菜看不懂定理证明,所以本篇博客不提供\(Matrix\ tree\)定理的证明内容(反正这个东西背结论就可以了是吧)
理解\(Matrix\ tree\)定理需要一定的线性代数知识(当然不会也没关系)
a.前置芝士——行列式
稍微费点笔墨写写行列式
行列式是一个\(N \times N\)的方阵,比如说下面就是一个\(3 \times 3\)的行列式
\(\left|\begin{array}{cccc} 1 & 6 & 9 \\ 7 & 0 & 7\\ 9 & 4 & 3 \end{array}\right|\)
下面我们统一某一个矩阵第\(i\)行第\(j\)列的元素为\(a_{i,j}\)
当然,行列式相比于矩阵的不同之处在于:行列式虽然长成了一个矩阵的样子,但它代表的是一个值,这个值的定义为\(\sum\limits_p s(p) \times \sum\limits_{i=1}^N a_{i,p_i}\),其中\(p\)是一个排列,\(s(p)=-1^{f(p)}\),\(f(p)\)等于排列\(p\)的逆序对数。
行列式有几个性质:
\(1.\)交换行列式的两行或者两列,行列式的值取相反数
\(2.\)给行列式的一行或一列的所有数同时乘上同一个值,行列式的值也会乘上这一个值
\(3.\)将一行列式的某一行(列)乘若干倍加到另一行(列)上,行列式的值不变
上面这些性质有什么用捏……定义中行列式的求值是\(O(n \times n!)\)的,有没有多项式做法呢……
我们可以使用类似于高斯消元的方法用\(O(n^3)\)的复杂度解决这个问题。可以发现我们在高斯消元中做的所有操作在行列式性质中都有相应的变换。
那么我们将其通过与高斯消元相同的方法将行列式变为上三角型(也就是\(i>j \rightarrow a_{i,j}=0\)的行列式),此时在定义式中能产生贡献的只有\(1,2...n\)排列,对应行列式对角线上的值的乘积。
上面说得比较浅显,如果不理解建议自行阅读《线性代数》相关内容
b.Matrix tree定理内容
对于一张连通无向图,定义其度数矩阵为矩阵\(a_{i,j}\),其中\(a_{i,j} = \left\{\begin{array}{rcl} d_i, & i=j \\ 0, & i \neq j \end{array}\right.\),用度数矩阵减去邻接矩阵得到基尔霍夫矩阵,划去基尔霍夫矩阵的第\(x\)行与第\(y\)列(\(x,y\)任意选定)得到一个新的行列式,这个行列式的值乘上\((-1)^{x+y}\)就是这个无向图的生成树数量。当然了为了方便一般就划掉第\(1\)行第\(1\)列或者第\(N\)行第\(N\)列。
这种东西暂时还不会证呢qwq
JSOI2008 最小生成树计数
先撸出一棵最小生成树出来,对于边权相等的边统一计算。在计算边权为某一个值的答案时,将最小生成树上其他的边连起来,将一个连通块看作一个点,将这一些边权相等的边与这些点看作新图,在新图上跑生成树计数,所有边权的答案的乘积就是最后答案
注意到这道题的模数比较NB,并不是一个质数,这意味着不能乘逆元。我们可以用类似辗转相除法的思路进行计算。对于当前需要减的两行,通过辗转相除计算系数与交换行的次数,然后再带入这两行中。
注意必须要将最小生成树上其他的边连起来,因为对于不连通的图矩阵行列式的值会等于\(0\)。
c.Matrix tree定理的一些拓展
有向图Matrix tree定理
对于外向生成树,度数矩阵变为入度矩阵;对于内向生成树,度数矩阵变为出度矩阵;如果生成树根为\(x\),则必须划掉第\(x\)行与第\(x\)列 ,其他与无向图Matrix tree定理一致。
如果记不得内外向生成树分别对应入度还是出度矩阵,就两个都试一下就好了
CQOI2018 社交网络
裸题,代码
所有生成树边权乘积的和
考虑如果边权都是整数,可以把边权为\(w\)的边看成\(w\)条重边,可以直接用定理,有理数每一行乘上分母的\(lcm\)将所有边权都乘成整数然后最后将答案除掉\(lcm^{N-1}\),那么Matrix tree定理显然也是正确的
所以一条边对度数矩阵和邻接矩阵的影响值都是它的边权。
SDOI2014 重建
设题目给出的边集为\(E\),某一棵生成树的边集为\(e\)
那么这一棵生成树的贡献是\(\prod\limits_{(u,v) \in e} G_{u,v} \times \prod\limits_{(u,v) \in E \&\& (u,v) \not\in e}(1-G_{u,v})=\prod\limits_{(u,v) \in E} (1 - G_{u,v}) \times \prod\limits_{(u,v) \in e} \frac{G_{u,v}}{1 - G_{u,v}}\)
然后套上板子就可以了
所有生成树边权和的和
注意这个和上面那个是不一样的
Matrix-Tree定理原本用来计算所有生成树边权的乘积的和,直接让它计算所有生成树边权的和的和,看起来似乎不可做
但实际上,可以利用多项式相关知识解决。值得注意的是,Matrix-Tree定理不仅适用于边权为有理数的情况,在边权是一个多项式的情况下Matrix-Tree定理仍然可以使用。
我们将一条边权为\(w\)的边看做一条边权为\(wx+1\)的边,注意后面是一个多项式,那么我们需要求的就是所有生成树的边权的乘积的和的一次项的值。
因为只需要求一次项,所以我们可以在\(\mod x^2\)的意义下解决,在这个意义下求逆也是很方便的(对于\(ax+b\),其逆\(cx+d\)只需要满足\(bd \mod mod = 1 , bc + ad \mod mod = 0\)),那么也能很快地求出行列式的值。
仍然需要注意:一条边对邻接矩阵和度数矩阵的影响值都是其边权
这里是一个求一个有向图所有外向生成树的边权和的和的sample