luoguP3317 [SDOI2014]重建 变元矩阵树定理 + 概率

Posted reverymoon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP3317 [SDOI2014]重建 变元矩阵树定理 + 概率相关的知识,希望对你有一定的参考价值。

技术分享图片

 

首先,我们需要求的是

$$sumlimits_{Tree} prodlimits_{E in Tree} E(u, v) prodlimits_{E otin Tree} (1 - E(u, v))$$

我们知道变元矩阵树定理 ---> 不知道请见此

我们自然希望要求和的事物只跟生成树的边有关

因此考虑把$prodlimits_{E otin Tree} (1 - E(u, v))$转化为$prodlimits_{E} (1 - E(u, v)) * frac{1}{prodlimits_{E in Tree} (1 - E(u, v))}$

也就是说,我们定义$e(u, v) = frac{p(u, v)}{1 - p(u, v)}$

然后就是变元矩阵树定理的裸题了......

复杂度$O(n^3)$

#include <cstdio>
#include <iostream>
using namespace std;

#define sid 55
#define ri register int
#define le long double
#define eps 1e-9

int n;
le all = 1, g[sid][sid], p[sid][sid];

le abs(le a) { return (a > 0) ? a : -a; }

le Guass() {
    for(ri i = 1; i < n; i ++) {
        int p = i;
        for(ri j = i; j < n; j ++)
        if(abs(g[j][i]) - abs(g[p][i]) > eps) p = j;
        swap(g[i], g[p]);
        for(ri j = i + 1; j < n; j ++) {
            le t = g[j][i] / g[i][i];
            for(ri k = i; k < n; k ++)
            g[j][k] -= g[i][k] * t;
        }
    }
    le ret = 1;
    for(ri i = 1; i < n; i ++) ret *= g[i][i];
    return ret;
}

int main() {
    cin >> n;
    for(ri i = 1; i <= n; i ++)
    for(ri j = 1; j <= n; j ++)
    cin >> p[i][j];
    for(ri i = 1; i <= n; i ++)
    for(ri j = 1; j <= n; j ++) {
        if(i == j) continue;
        if(p[i][j] > 1 - eps) p[i][j] = p[i][j] - eps;
        if(i < j) all *= (1 - p[i][j]);
        g[i][j] = p[i][j] / (1 - p[i][j]);
    }
    for(ri i = 1; i <= n; i ++)
    for(ri j = 1; j <= n; j ++)
    if(i != j) {
        g[i][i] += g[i][j];
        g[i][j] = -g[i][j];
    }
    printf("%.8Lf
", Guass() * all);
    return 0;
}

 

以上是关于luoguP3317 [SDOI2014]重建 变元矩阵树定理 + 概率的主要内容,如果未能解决你的问题,请参考以下文章

luogu3317 [SDOI2014]重建

P3317 [SDOI2014]重建

题解 P3317 [SDOI2014]重建

P3317 [SDOI2014]重建 变元矩阵树定理 高斯消元

[SDOI2014]重建

luoguP3313 [SDOI2014]旅行