变形的$Martix-Tree$定理
发现我们要求的是$\prod_{i \in E}{p_{i}} * \prod_{i \notin E}{(1-p_{i})}$
然后呢? 矩阵树对重边也有效对吧。考虑带权图,发现建出来的矩阵的任何一个$n-1$阶主子式的行列式的值都是其所有生成树的边权之积的和
那么就可以搞了,考虑每一条边权为$\frac{p_{i}}{(1-p_{i})}$,最后再乘一个$\prod{(1-p_{i})}$即可
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define eps 1e-10 7 #define N 55 8 using namespace std; 9 int n; 10 double g[N][N],a[N][N],ans=1,tmp=1; 11 void gauss(){ 12 n--; 13 for(int k=1;k<=n;k++){ 14 int bst=k; 15 for(int i=k+1;i<=n;i++) 16 if(fabs(a[i][k])>fabs(a[bst][k]))bst=i; 17 if(bst!=k){ 18 for(int i=k;i<=n;i++) 19 swap(a[k][i],a[bst][i]); 20 ans*=-1; 21 } 22 for(int i=k+1;i<=n;i++){ 23 double t=a[i][k]/a[k][k]; 24 for(int j=k;j<=n;j++) 25 a[i][j]-=t*a[k][j]; 26 } 27 ans*=a[k][k]; 28 } 29 } 30 int main(){ 31 scanf("%d",&n); 32 for(int i=1;i<=n;i++) 33 for(int j=1;j<=n;j++) 34 scanf("%lf",&g[i][j]); 35 for(int i=1;i<=n;i++){ 36 for(int j=i+1;j<=n;j++){ 37 if(g[i][j]==1)g[i][j]-=eps; 38 tmp*=(1-g[i][j]); 39 g[i][j]=g[i][j]/(1-g[i][j]); 40 a[i][i]+=g[i][j];a[j][j]+=g[i][j]; 41 a[i][j]=-g[i][j];a[j][i]=-g[i][j]; 42 } 43 } 44 gauss(); 45 printf("%0.10lf\n",ans*tmp); 46 return 0; 47 }