BZOJ3534: [Sdoi2014]重建【变元矩阵树定理】

3534: [Sdoi2014]重建

变元矩阵树定理

邻接矩阵中是可以带权的, w i j wij wij表示 i , j i,j i,j的边权, e i ei ei表示边。
定义 G ( i , j ) = G ( j , i ) = w i j G(i,j)=G(j,i)=wij G(i,j)=G(j,i)=wij,令 G ( i , i ) = − ∑ j ≠ i G ( i , j ) G(i,i)=−∑_{j≠i}G(i,j) G(i,i)=j=iG(i,j)

那么 n − 1 n−1 n1阶主子式的值为 ∑ T ⊆ T r e e ∏ e ∈ T w e \large \sum \limits_{T\subseteq Tree}\prod \limits_{e\in T}w_e TTreeeTwe

考虑题目中的概率,我们知道最后答案是 ∑ T ⊆ T r e e ∏ e ∈ T P e ∏ e ∉ T 1 − P e \large \sum \limits_{T \subseteq Tree} \prod \limits_{e\in T} P_e \prod \limits_{e \notin T}1-P_e TTreeeTPee/T1Pe

但是我们之间将边权设为 P ( i , j ) P(i,j) P(i,j)的话,最后答案就变成了 ∑ T ⊆ T r e e ∏ e ∈ T 1 − P e \large \sum \limits_{T\subseteq Tree}\prod \limits_{e\in T}1-P_e TTreeeT1Pe

所以我们考虑变一下这个式子,令 w i , j w_{i,j} wi,j P ( i , j ) 1 − P ( i , j ) \large \frac{P(i,j)}{1-P(i,j)} 1P(i,j)P(i,j)

式子就变成了 ∑ T ⊆ T r e e ∏ e ∈ T P e 1 − P e \large \sum \limits_{T\subseteq Tree}\prod \limits_{e\in T}\frac{P_e}{1-P_e} TTreeeT1PePe

然后将式子都乘上一个 ∏ e ( 1 − P e ) \prod \limits_{e} (1-P_e) e(1Pe)

就会发现式子变成了这样 ∑ T ⊆ T r e e ∏ e ∈ T P e ∏ e ∉ T 1 − P e \large \sum_{T \subseteq Tree} \prod \limits_{e\in T} P_e \prod \limits_{e \notin T}1-P_e TTreeeTPee/T1Pe

不就是我们要求的吗。

#include<cstdio>
#include<algorithm>
#define EXP 1e-8
using namespace std;
int n;double Tmp,f[55][55];
double _abs(double x){return x<0?-x:x;}
double Gauss(){
	double Mul=1.0;
	for(int i=1;i<n;i++){
		int k=i;
		for(int j=i+1;j<n;j++) if(_abs(f[i][i])<_abs(f[j][i])) k=j;
		swap(f[i],f[k]);
		if(_abs(f[i][i])<EXP) return 0;
		for(int j=i+1;j<n;j++){
			double t=f[j][i]/f[i][i];
			for(k=i;k<n;k++) f[j][k]-=t*f[i][k];
		}
		Mul*=f[i][i];
	}
	return _abs(Mul);
}
int main(){
	scanf("%d",&n);Tmp=1.0;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++){
		scanf("%lf",&f[i][j]);
		if(i!=j){
			if(f[i][j]<EXP) f[i][j]=EXP;//防止出现0
			if(f[i][j]>(1.0-EXP)) f[i][j]-=EXP;
			if(i<j)Tmp*=1.0-f[i][j];f[i][j]/=1.0-f[i][j];
		}
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++) if(j^i) f[i][i]-=f[i][j];
	printf("%.10lf\n",Gauss()*Tmp);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值