zoukankan      html  css  js  c++  java
  • LG P4284 [SHOI2014]概率充电器

    Description

    著名的电子产品品牌SHOI 刚刚发布了引领世界潮流的下一代电子产品—— 概率充电器:

    “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决 定!SHOI 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看 吧!”

    SHOI 概率充电器由$n-1$条导线连通了$n$ 个充电元件。进行充电时,每条导 线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率 决定。随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行 间接充电。

    作为SHOI 公司的忠实客户,你无法抑制自己购买SHOI 产品的冲动。在排 了一个星期的长队之后终于入手了最新型号的SHOI 概率充电器。你迫不及待 地将SHOI 概率充电器插入电源——这时你突然想知道,进入充电状态的元件 个数的期望是多少呢?

    Solution

    每个点能否被充电与其子树和子树外都有关,首先考虑子树内

    $$dp_{u}=prod _{v in son_{u}} dp_v+(1-dp_v) imes (1-p_{u,v}) $$

    再考虑子树外对概率的影响,因为$dp$由连乘计算得到,所以

    $$fa_v =frac{fa_u imes dp_u }{dp_v+(1-dp_v)(1-p_{u,v})}$$

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,tot,head[1000005];
    double q[500005],dp[500005],fa[500005],ans;
    struct Edge
    {
        int to,nxt;
        double w;
    }edge[1000005];
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return f*w;
    }
    void dfs1(int k,int f)
    {
        dp[k]=1-q[k];
        for(int i=head[k];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v!=f)
            {
                dfs1(v,k);
                dp[k]*=dp[v]+(1-dp[v])*(1-edge[i].w);
            }
        }
    }
    void dfs2(int k,int f)
    {
        for(int i=head[k];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v!=f)
            {
                double temp=fa[k]*dp[k]/(dp[v]+(1-dp[v])*(1-edge[i].w));
                fa[v]=temp+(1-temp)*(1-edge[i].w);
                dfs2(v,k);
            }
        }
    }
    int main()
    {
        n=read();
        for(int i=1;i<n;i++)
        {
            int a=read(),b=read();
            double p=read();
            edge[++tot]=(Edge){b,head[a],p/100};
            head[a]=tot;
            edge[++tot]=(Edge){a,head[b],p/100};
            head[b]=tot;
        }
        for(int i=1;i<=n;i++)
        {
            double x=read();
            q[i]=x/100;
        }
        dfs1(1,0);
        fa[1]=1;
        dfs2(1,0);
        for(int i=1;i<=n;i++)
        {
            ans+=1-dp[i]*fa[i];
        }
        printf("%.6lf
    ",ans);
        return 0;
    }
    [SHOI2014]概率充电器
  • 相关阅读:
    排列 POJ
    [kuangbin带你飞]专题二十一 概率&期望 部分题解
    队列最大值&滑动窗口最大值【剑指offer】
    Python实现可视化界面多线程豆瓣电影信息爬虫,并绘制统计图分析结果
    剑指offer【复杂链表的复制】
    树上博弈——从根节点先后走向叶子节点输赢【递归水题】
    给一个长度为n的字符串,找出长度为m的最小字典子序列【单调栈】
    Hrbust 1814 小乐乐的化妆品【01背包】
    Hrbust 1541集合划分 & Hrbust 2002幂集【dp】
    Hrbust 1333 GG的关心【01背包】
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13743271.html
Copyright © 2011-2022 走看看