Remove the unselected edges and make a contribution of \ (1-g \) to the answer . This question is completely a matrix-tree board. Consider how to get rid of \ (1-g \) .
An edge is changed from unselected to selected, and its contribution is changed from \ (1-g \) to \ (g \) , so the edge weight is \ (\ frac g {1-g} \) .
#include <cstdio>
#include <cmath>
#include <algorithm>
const int MAXN = 59;
const double EPS = 1e-12;
double a[MAXN][MAXN], s = 1.0;
double det(int n){
double res = 1.0;
for(int i = 1; i <= n; ++i){
int r = i;
for(int j = i + 1; j <= n; ++j)
if(std::fabs(a[r][i]) < std::fabs(a[j][i]))
r = j;
if(i ^ r){
std::swap(a[i], a[r]);
res = -res;
}
if(std::fabs(a[i][i]) < EPS)
return 0;
for(int j = i + 1; j <= n; ++j){
double d = a[j][i] / a[i][i];
for(int k = i; k <= n; ++k)
a[j][k] -= a[i][k] * d;
}
res *= a[i][i];
}
return res;
}
double g[MAXN][MAXN];
int n;
inline void insert(int u, int v, double m){
a[u][u] += m, a[v][v] += m;
a[u][v] -= m, a[v][u] -= m;
}
int main(){
std::scanf("%d", &n);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
std::scanf("%lf", &g[i][j]);
for(int i = 1; i <= n; ++i)
for(int j = i + 1; j <= n; ++j)
insert(i, j, g[i][j] / (1.0 - g[i][j] + EPS)), s *= (1.0 - g[i][j] + EPS);
std::printf("%.12f\n", s * det(n - 1));
return 0;
}