• [ZJOI2015]地震后的幻想乡


    LINK:洛谷

    题目大意:

    现在有一个$n$个点,$m$条边的无向图,每条边的边权是一个$[0,1]$的随机实数,求最小生成树的最大权值$X$的期望。

     $n\leq 10,m\leq \frac{n*(n-1)}{2}$


    这道题有非常多的做法,其中我写一个数学味道最浓的做法。

    设$p(t)=P'(t),P(t)=Pr(X\geq t)$,显然$p(t)$表示$X=t$的概率。

    则答案就是$$\int_{0}^1p(x)xdx=\int_{0}^1p(x)\int_{0}^xdtdx$$

    $$=\int_{0}^1\int_{t}^{1}p(x)dxdt$$

    $$=\int_{0}^1P(t)dt$$

    现在我们考虑如何求它。

    我们考虑对子集dp。

    但是在不连通的情况下,有很多个集合,我们要选取哪一个呢?

    其实都是可以的,因为联通之后只有一个集合,所以我们钦定一个点1,设$S$为在$t$时刻时与1联通的所有点。

    设$P_S(t)$为点集$S$对应的$P(t)$。

    我们需要$X\geq t$,所以这个图在$t$时刻不连通,设$t$时刻与$1$联通的有$S0$这些点,则$S0$联通且$S0$与$S-S0$之间的所有边的权值$>t$

    我们用$T(S1,S2)$表示$S1$和$S2$之间的边的数量。

    $$P_S(t)=\sum_{1\in S_0\subset S}(1-t)^{T(S_0,S-S_0)}(1-P_{S_0}(t))$$

    所以

    $$\int_{0}^1P_S(t)(1-t)^kdt=\sum_{1\in S_0\subset S}\int_{0}^1(1-t)^{T(S_0,S-S_0)+k}(1-P_{S_0}(t))dt$$

    $$=\sum_{1\in S_0\subset S}(\int_0^1(1-t)^{T(S_0,S-S_0)+k}dt-\int_0^1(1-t)^{T(S_0,S-S_0)+k}P_{S_0}(t)dt)$$

    $$=\sum_{1\in S_0\subset S}(\frac{1}{1+k+T(S_0,S-S_0)}-\int_0^1(1-t)^{T(S_0,S-S_0)+k}P_{S_0}(t)dt)$$

    然后我们就可以开始dp了

    设$dp[S][k]$表示$\int_{0}^1P_S(t)(1-t)^kdt$

    然后代码出奇的短。

    复杂度$O(3^n*m)$,但是这是一个较松的上界。

     1 #include<cstdio>
     2 #define Rint register int
     3 using namespace std;
     4 int n, m, link[1 << 10], siz[1 << 10];
     5 double f[1 << 10][46];
     6 int main(){
     7     scanf("%d%d", &n, &m);
     8     for(Rint i = 1;i <= m;i ++){
     9         int x, y;
    10         scanf("%d%d", &x, &y); -- x; -- y;
    11         link[x] |= (1 << y);
    12         link[y] |= (1 << x);
    13     }
    14     for(Rint i = 1;i < (1 << n);i ++) siz[i] = siz[i & (i - 1)] + 1;
    15     for(Rint S = 3;S < (1 << n);S += 2){
    16         for(Rint S0 = (S - 1) & S;S0;S0 = (S0 - 1) & S) if(S0 & 1){
    17             int T = 0;
    18             for(Rint i = 0;i < n;i ++) if((S >> i) & (~S0 >> i) & 1)
    19                 T += siz[link[i] & S0];
    20             for(Rint i = 0;i + T <= m;i ++)
    21                 f[S][i] += 1.0 / (1 + i + T) - f[S0][i + T];
    22         }
    23     }
    24     printf("%.6lf\n", f[(1 << n) - 1][0]);
    25 }
  • 相关阅读:
    USART串口通信实验
    EXTI 外部中断
    NVIC中断优先级管理
    实验1 跑马灯实验
    redis集群部署---一台主机
    zookeeper服务启动报错---Error contacting service. It is probably not running.
    shell脚本学习笔记
    最短路径算法——Floyd算法
    一篇文章学懂Shell脚本(摘抄)
    VIM空格和TAB转换
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/10482794.html
Copyright © 2020-2023  润新知