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

    P4284 [SHOI2014]概率充电器

    链接:https://www.luogu.org/problemnew/show/P4284

    题目描述

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

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

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

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

    输入输出格式

    输入格式:

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

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

    第n+2 行n 个整数:qi。表示i 号元件直接充电的概率为qi%。

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    3
    1 2 50
    1 3 50
    50 0 0
    输出样例#1: 复制
    1.000000
    输入样例#2: 复制
    5
    1 2 90
    1 3 80
    1 4 70
    1 5 60
    100 10 20 30 40
    输出样例#2: 复制
    4.300000

    说明

    对于30%的数据,n≤5000。

    对于100%的数据,n≤500000,0≤p,qi≤100。

    题解:概率dp,正难求反,求充不上的概率

    #include<bits/stdc++.h>
    using namespace std;
    #define eps 1e-6
    #define maxn 500005
    double f[maxn],g[maxn],h[maxn];
    int tot,head[maxn];
    struct edge{
        int nxt,to;double w;
    }G[maxn * 2 + 10];
    void add(int u, int v, double w){
        G[++tot].to = v;
        G[tot].w = w;
        G[tot].nxt = head[u];
        head[u] = tot;
    }
    void dfs1(int u, int fa){//儿子的贡献
        
        for(int i = head[u]; i; i = G[i].nxt){
            int v = G[i].to;
            if(v == fa)continue;
            dfs1(v, u);        
            h[v] = f[v] + (1 - f[v]) * (1 - G[i].w);//儿子充不上电的概率+儿子冲上电的概率*导线无电概率
            f[u] *= h[v];
        }
    }
    void dfs2(int u, int fa){    //父亲的贡献    
        
        for(int i = head[u]; i; i = G[i].nxt){
            int v = G[i].to;
            if(v == fa)continue;            
            double t = (f[v] < eps) ? 0 : g[u] * f[u]/h[v];//父亲充不上电的概率,要出去他本身对父亲的贡献
            g[v] = (1 - t)*(1 - G[i].w) + t;
            dfs2(v, u);
        }
    }
    /*
        t =  g[fa] * f[fa] / f[u]
        g[u] = t + (1 - t)*(1 - w[fa][u])
    
    */
    int main(){
        int n;
        double ans = 0;
        scanf("%d",&n);
        for(int i = 1; i < n; i++){
            int u, v, c;
            scanf("%d%d%d",&u,&v,&c);
            add(u, v, c/100.0);add(v, u, c/100.0);
        }
        for(int i = 1; i <= n; i++){
            int c;scanf("%d",&c);
            f[i] = 1 - c/100.0;
        }
        dfs1(1, 0);
        f[0] = 1; g[1] = 1;
        dfs2(1, 0);
        for(int i = 1; i <= n; i++)
            ans += (1 - f[i]*g[i]);//充上的概率=(1-父亲、儿子都让他充不上)
        printf("%.6lf
    ",ans);
    }
  • 相关阅读:
    Chrome 和 FireFox 查看伪类:active,:hover,:focus样式
    为什么需要清除浮动float,及解决办法
    Chrome 控制台使用之配置网速
    Vue 和 浏览器 之Vue项目在浏览器中运行并使用debug
    CSS里不为人知的秘密(02)之常见属性使用
    ImageMagick 简单使用
    php 使用gmail发送邮件之---gmail授权申请开通
    vue复习知识记录【2】 v-if v-show vfor
    vue复习知识记录【1】 绑定字段、绑定事件、使用方法、使用计算
    解决Selenium下使用Firefox的findElement速度非常慢的问题
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/8992731.html
Copyright © 2011-2022 走看看