• [SHOI2014]概率充电器 题解


    注意到本题的贡献是不带权的,所以期望其实就是每个点的概率之和。
    本题正着做好像不是很好做,要考虑 (P(A+B)=P(A)+P(B)-P(A)P(B)) 的容斥(因为这是两个条件至少满足一个,所以是求集合并的概率),具体可以看这个
    所以我们考虑反着做。设 (f_u) 表示 (u) 点没有通电的概率,那么有

    [f_u=(1-p_u)prod_{vin(u,v)}(1-p(u,v)+p(u,v)f_v) ]

    这个点先要自己不亮,然后周围的点要么边不导电,要么边导电但链接的那个不通电,注意到后面那个其实算的是 (P(A)+P(A|B))
    发现有后效性,我们考虑换根 DP,重新设 (f_u) 表示只考虑在 (u) 的子树中的点使得 (u) 不亮的概率,于是刚才的式子变成了

    [f_u=(1-p_u)prod_{vin{ m son}(u)}(1-p(u,v)+p(u,v)f_v) ]

    第一遍 DP 后根的答案已经正确了,考虑从 (fa) 推向 (u),设 (g_u) 是根为 (u) 时的答案。有

    [g_u=f_uleft(1-w(u,fa)+frac{w(u,fa)g_{fa}}{1-w(u,fa)+w(u,fa)f_u} ight) ]

    注意要判断除数为 (0) 的情况,提供一组 hack 数据:

    Input:
    3
    1 2 100
    2 3 100
    0 100 0
    Output:
    3.000000
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=5e5+5;
    struct Edge{int to,nxt;double w;}e[N*2];
    int n,head[N],cntE;
    double ans,p[N],f[N],g[N];
    
    inline void add(int u,int v,double w) {e[++cntE]=(Edge){v,head[u],w},head[u]=cntE;}
    
    void dfs1(int u,int fa)
    {
        f[u]=1-p[u];
        for(int i=head[u],v;i;i=e[i].nxt)
            if((v=e[i].to)!=fa)
                dfs1(v,u),f[u]*=(1-e[i].w+e[i].w*f[v]);
    }
    
    void dfs2(int u,int fa)
    {
        ans+=1-g[u];
        for(int i=head[u],v;i;i=e[i].nxt)
            if((v=e[i].to)!=fa)
            {
                if(e[i].w+e[i].w*f[v]==1) g[v]=f[v];
                else
                {
                    double tmp=g[u]/(1-e[i].w+e[i].w*f[v]);
                    g[v]=f[v]*(1-e[i].w+e[i].w*tmp);
                }
                dfs2(v,u);
            }
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1,a,b;i<n;++i)
        {
            double c;
            scanf("%d%d%lf",&a,&b,&c); c/=100;
            add(a,b,c); add(b,a,c);
        }
        for(int i=1;i<=n;++i) scanf("%lf",p+i),p[i]/=100;
        dfs1(1,0); g[1]=f[1]; dfs2(1,0);
        printf("%.6f",ans);
        return 0;
    }
    
  • 相关阅读:
    补发《超级迷宫》站立会议九
    补发《超级迷宫》站立会议八
    补发《超级迷宫》站立会议七
    补发《超级迷宫》站立会议六
    一周开发项目
    所学的内容
    开发项目和所用时间 感想
    自我介绍
    大容量数据转移操作命令——BULK INSERT(类似于BCP)
    字符编码与文件处理
  • 原文地址:https://www.cnblogs.com/wzzyr24/p/13450913.html
Copyright © 2020-2023  润新知