【矩阵树定理 学习笔记】

版权声明:2018/4/10重启blog;转载请注明出处 https://blog.csdn.net/zhaiqiming2010/article/details/81503613

矩阵树定理的作用?

主要用来解决生成树计数问题

准备

对于给定的无向图G

定义度数矩阵D[G] 满足:当ij时,dij=0;当i=j时,dij等于vi的度数。

定义邻接矩阵A[G] 满足:当ij时,如果节点i和节点j之间存在边,dij=1;当i=j时,dij = 0。

定义给定的无向图G的基尔霍夫矩阵C[G] = D[G] - A[G]。
 

G的生成树的个数 = C[G]任何一个n-1阶主子式的行列式的绝对值。

证明

1.基尔霍夫矩阵的行列式一定都是0,因为基尔霍夫矩阵的任意行或列的和都是0。

2.如果G是不连通的,则它的基尔霍夫矩阵的任一个主子式的行列式均为0。

当G不连通的时候,G中存在多个联通分量,将存在于同一个联通分量的点通过交换行和列使其相邻,假设存在K(k>1)个联通分量,行交换的次数为x次,那么列交换的次数一定也为x次,总交换次数为2*x次,所以矩阵的符号不变。

交换完成之后如图(图片来自 周东《生成树的计数及其应用》)

                                                            

图中的框中的G1...Gk都代表在给出的G中的联通分量的基尔霍夫矩阵,所以|C[G1]| .... |C[Gk]|都为0。

所以对于n-1阶主子式的行列式,对角线求乘积,除了去掉的一行一列所在的矩阵,其余的矩阵的行列式的值都为0,所以n-1阶主子式的行列式的值为0。

3.如果G是一颗树,那么它的Kirchhoff矩阵C的任一个n-1阶主子式的行列式均为1。

 

O(n^3)高斯消元计算行列式的值

bool zero(double a)
{
	return a>-eps && a<eps;
}
double Gauss()
{
	double mul,Result=1;
	int i,j,k,b[n];
	for(i=0;i<n;i++) b[i]=i;
	for(i=0;i<n;i++){
		if(zero(a[b[i]][i]))
			for(j=i+1;j<n;j++)
				if(!zero(a[b[j]][i])) { swap(b[i],b[j]); Result*=-1; break;  }
		Result*=a[b[i]][i];
		for(j=i+1;j<n;j++)
			if(!zero(a[b[j]][i])){
				mul=a[b[j]][i]/a[b[i]][i];
				for(k=i;k<n;k++)
					a[b[j]][k]-=a[b[i]][k]*mul;
			}
	}
	return Result;
}

 

参考资料:周东《生成树的计数及其应用》

 

 

猜你喜欢

转载自blog.csdn.net/zhaiqiming2010/article/details/81503613