• 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);
    }
  • 相关阅读:
    新概念第二册(1)--英语口语听力课1
    外企面试课程(一)---熟悉常见的缩略词
    公司 邮件 翻译 培训 长难句 结课
    workflow
    公司 邮件 翻译 培训 长难句 20
    公司 邮件 翻译 培训 长难句 19
    Engineering Management
    公司 邮件 翻译 培训 长难句 18
    公司 邮件 翻译 培训 长难句 17
    第14.5节 利用浏览器获取的http信息构造Python网页访问的http请求头
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/8992731.html
Copyright © 2020-2023  润新知