• [BZOJ]3566: [SHOI2014]概率充电器


      题解:   很早之前就想做的树dp

    正着情况太多 我们考虑反着过来考虑 $ dp[x] $表示x的子树和x本身使x不导通的概率

    然后类似于容斥 从上到下维护每个点被接通的概率即可

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=5e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    
    double dp[MAXN],up[MAXN];
    int a[MAXN];
    
    void dfs(int x,int pre){
        dp[x]=1.0*(100-a[x])/100;
        link(x){
    	if(j->t==pre)continue;
    	dfs(j->t,x);
    	dp[x]*=(dp[j->t]+1.0*(1-dp[j->t])*(100-j->v)/100);
        }
    }
    
    double b[MAXN];
    double st[MAXN],St[MAXN];
    double ans[MAXN];
    int tot;
    
    void _dfs(int x,int pre){
        tot=0;
        link(x){
    	if(j->t==pre)continue;
    	b[++tot]=dp[j->t]+(1-dp[j->t])*(100-j->v)/100;
        }
        st[0]=St[tot+1]=1.0;
        inc(i,1,tot)st[i]=st[i-1]*b[i];
        dec(i,tot,1)St[i]=St[i+1]*b[i];
        int cnt=0;
        link(x){
    	if(j->t==pre)continue;
    	cnt++;
    	up[j->t]=up[x]*st[cnt-1]*St[cnt+1];
    	double t=up[j->t]+1.0*(1.0000-up[j->t])*(100-j->v)/100;
    	up[j->t]=t;
    	ans[j->t]=1.0-up[j->t]*dp[j->t];
    	up[j->t]*=1.0*(100-a[j->t])/100;
        }
        link(x){
    	if(j->t==pre)continue;
    	_dfs(j->t,x);
        }
    }
    
    int main(){
        int n=read();
        int x,y,z;
        inc(i,2,n)x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
        inc(i,1,n)a[i]=read();
        up[1]=1.0*(100-a[1])/100;
        dfs(1,0);_dfs(1,0);
        ans[1]=1.00000-dp[1];
        double ans1=0;
        inc(i,1,n)ans1+=ans[i];
        printf("%.6f
    ",ans1);
    }
    

      

    3566: [SHOI2014]概率充电器

    Time Limit: 40 Sec  Memory Limit: 256 MB
    Submit: 1981  Solved: 921
    [Submit][Status][Discuss]

    Description

    著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:
    “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧!

    SHOI 概率充电器由 n-1 条导线连通了 n 个充电元件。进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定。
    随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行间接充电。
    作为 SHOI 公司的忠实客户,你无法抑制自己购买 SHOI 产品的冲动。在排了一个星期的长队之后终于入手了最新型号的 SHOI 概率充电器。
    你迫不及待地将 SHOI 概率充电器插入电源——这时你突然想知道,进入充电状态的元件个数的期望是多少呢?

    Input

    第一行一个整数:n。概率充电器的充电元件个数。充电元件由 1-n 编号。
    之后的 n-1 行每行三个整数 a, b, p,描述了一根导线连接了编号为 a 和 b 的
    充电元件,通电概率为 p%。
    第 n+2 行 n 个整数:qi。表示 i 号元件直接充电的概率为 qi%。

    Output

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

    Sample Input

    3
    1 2 50
    1 3 50
    50 0 0

    Sample Output

    1.000000

    HINT

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

  • 相关阅读:
    web项目中添加logger日志
    oracle 创建表空间
    从request中读数据流
    通过request获取ID地址的方法
    创建表空间的sql语句
    plsql点击不再提示后需重新提示
    js文件报错Syntax error on token "Invalid Regular Expression Options", no accurate correction
    java知识
    DevC++出现[Error] ld returned 1 exit status,如何解决才好呢?
    1
  • 原文地址:https://www.cnblogs.com/wang9897/p/10471952.html
Copyright © 2020-2023  润新知