标签:一个 printf class rip link mat 生成 答案 isp
一个 \(n\) 个点的图 \(G\),每两个点之间都有一个概率 \(p_{i,j}\) 存在一条边。求存在生成树的概率。
对于一个特定的生成树 \(T\),其边集为 \(E\),那么生成它的概率就是
即出现树边的概率积乘上不出现非树边的概率积。那么所有生成树的概率就是
但是这并不能直接套 Matrix-tree 。考虑到 Matrix-tree 求的是所有生成树的边权积之和,所以需要想办法将后面的式子化成边权积。不难发现,如果把边权设成 \(\frac{p_e}{1-p_e}\) 就能很好的解决这个问题。答案即为
还有一个问题,对于一条边,其出现的概率可能是 1。这就直接导致了分母为 0,除法会出问题。一开始想的是有没有什么做法可以求给定确定边的生成树个数,然后后面放弃了……转而回来想先前的做法。主要问题在于不能除 0,然后我非常灵性地对所有数加了一个 \(eps=10^{-10}\) ……竟一发过了。
复杂度 \(O(n^3)\)
#include<stdio.h>
#define N 53
#define eps 1e-10
int n;
double a[N][N];
int main(){
scanf("%d",&n);
double ans=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
double x;
scanf("%lf",&x);
x+=eps;
if(i!=j) a[i][j]=-x/(1-x),a[i][i]+=x/(1-x);
if(i<j) ans*=(1-x);
}
for(int i=2;i<=n;i++){
for(int j=i+1;j<=n;j++){
double t=a[j][i]/a[i][i];
for(int k=i;k<=n;k++)
a[j][k]-=a[i][k]*t;
}
ans*=a[i][i];
}
printf("%.4lf",ans);
}
/*
3
0 0.5 0.5
0.5 0 0.5
0.5 0.5 0
*/
标签:一个 printf class rip link mat 生成 答案 isp
原文地址:https://www.cnblogs.com/wwlwQWQ/p/14350365.html