5899. 【NOIP2018模拟10.6】资源运输(矩阵树定理)

题目大意:

要你求一张图的生成树的边权乘积期望。

思路:

这题是一个矩阵树和变元矩阵树定理的应用题,矩阵树可以求出来生成树的数量,变元后的矩阵树可以求出所有生成树乘积和,然后除一下就好了。
矩阵树写法如下:
先定义两个矩阵,一个是度数矩阵,一个是连接矩阵,用度数矩阵剪掉连接矩阵,然后去掉一行一列,然后高斯消元,把对角线所有数乘起来就好了。

程序:

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define mo 998244353
#define N 305
using namespace std;

int n,m,x,y,z;
LL a[N][N],b[N][N];

LL mul(LL x,int y){
	if (y==1) return x;
	LL o=mul(x,y/2);
	o=(o*o)%mo;
	if (y%2==1) o=(o*x)%mo;
	return o;
}

LL det(){
	LL ans=1;
	for (int i=1;i<=n;i++){
		LL inv=mul(a[i][i],mo-2);
		for (int j=i+1;j<=n;j++){
			LL rate=a[j][i]*inv%mo;
			for (int k=i;k<=n;k++){
				a[j][k]=(a[j][k]+mo-rate*a[i][k]%mo)%mo;
			}
		}
		ans=(ans*a[i][i])%mo;
	}
	return ans;
}

int main(){
	freopen("avg.in","r",stdin);
	freopen("avg.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++) {
		scanf("%d%d%d",&x,&y,&z);
		a[x][y]=mo-1;
		a[y][x]=mo-1;
		a[x][x]++;
		a[y][y]++;
		b[x][y]=mo-z;
		b[y][x]=mo-z;
		b[x][x]=(b[x][x]+z)%mo;
		b[y][y]=(b[y][y]+z)%mo;
	}
	n--;
	LL B=det();
	for (int i=1;i<=n;i++)
	 for (int j=1;j<=n;j++)
	  a[i][j]=b[i][j];
	LL A=det();
	printf("%lld",A*mul(B,mo-2)%mo);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值