【jzoj3661】【SHTSC2014】【概率充电器】【期望】

66 篇文章 0 订阅
10 篇文章 0 订阅

题目大意

著名的电子产品品牌SHOI刚刚发布了引领世界潮流的下一代电子产品——概率充电器:
“采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧!”
SHOI概率充电器由n-1条导线连通了n个充电元件。进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定。随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行间接充电。
作为SHOI公司的忠实客户,你无法抑制自己购买SHOI产品的冲动。在排了一个星期的长队之后终于入手了最新型号的SHOI概率充电器。你迫不及待地将SHOI概率充电器插入电源——这时你突然想知道,进入充电状态的元件个数的期望是多少呢?

解题思路

考虑计算充电的期望很复杂,考虑分别计算以1为根,从上到下,从下到上充不上电的概率。先计算从下到上,再计算从上到下即可。考虑到会爆栈,用bfs即可。

code

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LF double
#define LL long long
#define ULL unsigned long long
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
using namespace std;
int const mn=5*1e5+9,mm=1e6+9,inf=1e9+7;
int n,gra,begin[mn],to[mm],next[mm],q[mn],inq[mn];
LF f[mn],g[mn],len[mm],a[mn];
void insert(int u,int v,LF w){
    to[++gra]=v;
    len[gra]=w;
    next[gra]=begin[u];
    begin[u]=gra;
}
int main(){
    //freopen("charger.in","r",stdin);
    //freopen("charger.out","w",stdout);
    freopen("d.in","r",stdin);
    freopen("d.out","w",stdout);
    scanf("%d",&n);
    fo(i,1,n-1){
        int a,b;LF p;
        scanf("%d%d%lf",&a,&b,&p),p/=100;
        insert(a,b,p);
        insert(b,a,p);
    }
    fo(i,1,n)scanf("%lf",&a[i]),a[i]/=100;
    int ti=0;
    inq[q[++ti]=1]=1;
    fo(i,1,n){
        int now=q[i];
        fr(j,now)if(!inq[to[j]])inq[q[++ti]=to[j]]=1;
    }
    fo(i,1,n)inq[i]=0;
    fd(i,n,1){
        int now=q[i];inq[now]=1;
        f[now]=1-a[now];
        fr(j,now)if(inq[to[j]]){
            f[now]*=1-len[j]*(1-f[to[j]]);
        }
    }
    g[1]=1;
    fo(i,1,n)inq[i]=0;
    fo(i,1,n){
        int now=q[i];inq[now]=1;
        fr(j,now)if(!inq[to[j]]){
            if(1-len[j]*(1-f[to[j]]))g[to[j]]=1-len[j]*(1-f[now]*g[now]/(1-len[j]*(1-f[to[j]])));
            else g[to[j]]=1-len[j];
        }
    }
    LF ans=0;
    fo(i,1,n)ans+=1-f[i]*g[i];
    printf("%.6lf",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值