这里有个奇怪的词条 变元矩阵-树定理
也就是说 基尔霍夫矩阵的任意一个代数余子式是所有生成树的边权积的和
我们直接会得出
∑T∏e∈Tpe
但这样不对 应该是
∑T(∏e∈Tpe∏e∉T(1−pe))
所以我们变幻一下边权 求出
∑T∏e∈Tpe(1−pe)
再乘上 ∏e(1−pe) 得
∏e(1−pe)∑T∏e∈Tpe(1−pe)
就是答案
这里有个小trick
当 p=1 把它当做 1−ϵ 处理
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef double ld;
const int N=55;
const ld eps=1e-8;
int n; ld a[N][N];
inline double det(int n){
ld ret=1;
for (int i=1;i<=n;i++){
int r=i;
for (int j=i+1;j<=n;j++) if (fabs(a[r][i])<fabs(a[j][i])) r=j;
if (i!=r) for (int j=i;j<=n;j++) swap(a[i][j],a[r][j]);
if (fabs(a[i][i])<eps) return 0.0;
for (int j=i+1;j<=n;j++){
ld t=a[j][i]/a[i][i];
for (int k=i;k<=n;k++)
a[j][k]-=a[i][k]*t;
}
}
for (int i=1;i<=n;i++) ret*=a[i][i];
return fabs(ret);
}
int main(){
double tmp=1.0,Ans;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++){
scanf("%lf",&a[i][j]);
if (i==j) continue;
if (a[i][j]>1.0-eps) a[i][j]-=eps;
if (i<j) tmp*=1-a[i][j];
a[i][j]/=1-a[i][j];
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (i!=j)
a[i][i]+=a[i][j],a[i][j]=-a[i][j];
Ans=det(n-1)*tmp;
printf("%.10lf\n",Ans);
return 0;
}