矩阵树定理

数生成树数。

对于无向图

记度数矩阵 ,。邻接矩阵 , 等于 的数量。定义 基尔霍夫矩阵 ,则 去掉 行 列 得到 , 的行列式 为图的生成树数量。

对于有向图

分 叶向树和根向树,将度数分别换为入度和出度,删去 行 列的行列式为以 为根的方案数。

模板:P6178

int n,m,op;
int a[maxn][maxn];
int det(int n){
	int ans=1;
	for(int i=2;i<=n;i++){
		for(int j=i+1;j<=n;j++)if(a[j][i]){
			while(a[i][i]){
				int d=a[j][i]/a[i][i];
				for(int k=i;k<=n;k++)(a[j][k]+=mod-a[i][k]*d%mod)%=mod;
				swap(a[i],a[j]),ans=mod-ans;
			}
			swap(a[i],a[j]),ans=mod-ans;
		}
	}
	for(int i=2;i<=n;i++)ans=ans*a[i][i]%mod;
	return ans;
}
void work(){
	n=read();m=read();op=read();
	for(int i=1;i<=m;i++){
		int u=read(),v=read(),w=read();
		if(!op)(a[u][u]+=w)%=mod,(a[v][v]+=w)%=mod,(a[u][v]+=mod-w)%=mod,(a[v][u]+=mod-w)%=mod;
		else (a[v][v]+=w)%=mod,(a[v][u]+=mod-w)%=mod;
	}
	printf("%lld\n",det(n));
}

生成树带权值

如果求图的 生成树每条边的权值之积 的和,将 和 的值改为对应的权值和。

P3317

对于一颗生成树 ,权值为 。把 提出来,生成树每条边的权值为 。

BEST 定理

对于欧拉图(有向图,存在欧拉回路,入度等于出度,除了孤立点强连通),从 出发的欧拉回路等于以 为根的根向树的方案数乘以 。

P7531

建源汇点,再从 向 连 条边,此时是欧拉图。随便选一个根求内向树,还要除去 并不能随便定向。

相关技巧

P6624

莫比乌斯反演除去 的贡献。此时生成树的权值为每条边之和,但矩阵树做的是每条边之积。权值 之积模 的一次项权值,维护一个结构体的行列式。

P5296

求所有生成树权值和的 次方的和。

行列式的一个元素中维护 的所有值,乘法为二项式定理 ,逆元递推。复杂度 。

P4208

最小生成树每种边权选的边数量相等。求出一个 MST 之后,把同个边权的边拉出来,先连上其他边权的边,把每层内的生成树数量乘起来。

Q9278

对初始为 的 矩阵操作 次,对 的 加 。求矩阵的行列式。

。

二维差分后行列式值不变,等价于连边 后图的基尔霍夫矩阵的行列式,即生成树方案数。注意到 ,广义串并联方法,点数 ,求出缩完之后每条边在/不在生成树的方案数 和 。提出 ,边权为 再矩阵树定理求生成树权值。