zoukankan      html  css  js  c++  java
  • 洛谷 P4284 [SHOI2014]概率充电器 解题报告

    P4284 [SHOI2014]概率充电器

    题目描述

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

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

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

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

    输入输出格式

    输入格式:

    第一行一个整数:(n)。概率充电器的充电元件个数。充电元件由 (1-n) 编号。

    之后的 (n-1) 行每行三个整数(a,b,p) ,描述了一根导线连接了编号为 (a)(b) 的 充电元件,通电概率为(p\%)

    (n+2)(n) 个整数:(q_i)。表示 (i) 号元件直接充电的概率为 (q_i\%)

    输出格式:

    输出一行一个实数,为能进入充电状态的元件个数的期望,四舍五入到小数点后6位小数。

    说明

    对于(30\%)的数据,(n≤5000)

    对于(100\%)的数据,(n≤500000)(0≤p,q_i≤100)


    果然一做期望题就暴露自己脑子蠢的事实了=-=

    首先我读错题了,但是我觉得不能怪我啊,难道题目说的不就是只有自己激发的才能传火给别人嘛...

    然后我花了好久才发现这个题就是在算概率。

    每个点可以从所有其他点获取传火概率,做一个换跟dp就行了,具体的

    (dp_i)先处理出子树(i)的贡献,然后直接换跟做就可以了。

    需要注意的地方,传火的时候要减去两个都有,换跟中有一个类似退背包的过程需要处理分母为0


    Code:

    #include <cstdio>
    #include <cmath>
    const int N=5e5+10;
    const double eps=1e-8;
    int head[N],to[N<<1],Next[N<<1],cnt;
    double dp[N],ans,edge[N<<1];
    void add(int u,int v,double w)
    {
        to[++cnt]=v,edge[cnt]=w,Next[cnt]=head[u],head[u]=cnt;
    }
    void dfs1(int now,int fa)
    {
        for(int v,i=head[now];i;i=Next[i])
            if((v=to[i])!=fa)
            {
                dfs1(v,now);
                dp[now]=dp[now]+dp[v]*edge[i]-dp[now]*dp[v]*edge[i];
            }
    }
    void dfs2(int now,int fa,double p)
    {
        dp[now]=dp[now]+p-dp[now]*p;
        ans+=dp[now];
        for(int v,i=head[now];i;i=Next[i])
            if((v=to[i])!=fa)
            {
                if(fabs(dp[v]*edge[i]-1)<eps) p=dp[now];
                else p=(dp[now]-dp[v]*edge[i])/(1-dp[v]*edge[i]);
                dfs2(v,now,p*edge[i]);
            }
    }
    int main()
    {
        int n;scanf("%d",&n);
        for(int u,v,w,i=1;i<n;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,1.0*w/100),add(v,u,1.0*w/100);
        }
        for(int i=1;i<=n;i++) scanf("%lf",dp+i),dp[i]/=100.0;
        dfs1(1,0);
        dfs2(1,0,0);
        printf("%.6lf
    ",ans);
        return 0;
    }
    

    2019.1.13

  • 相关阅读:
    项目笔记:统计页面功能实现
    jquery easyui datagrid实现数据改动
    Skia图片解码模块流程分析
    TRIZ的成功案例
    基于HTML5的Web SCADA工控移动应用
    webservices系列(五)——javaweb整合Axis2及多service配置
    org.hibernate.PropertyValueException: not-null property references a null or transient value: model.
    线程池和异步线程
    [leetcode]Implement strStr()
    Python工作日类库Busines Holiday介绍
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10262582.html
Copyright © 2011-2022 走看看