博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【题解】 P4284 [SHOI2014]概率充电器
阅读量:6192 次
发布时间:2019-06-21

本文共 1925 字,大约阅读时间需要 6 分钟。

\(Description:\)

一棵树,每个点q[i]的概率直接充电,每条边p[i]的概率导电,电可以沿边传递使其他点间接充电。求进入充电状态的点期望个数。

\(Sample\) \(Iuput:\)

3

1 2 50
1 3 50
50 0 0

\(Sample\) \(Input:\)

5

1 2 90
1 3 80
1 4 70
1 5 60
100 10 20 30 40

\(Solution:\)

考虑树形dp,首先我们需要明白,其实我们要求的期望就是概率之和,那么我们只要求出每个点的概率,那么怎么求每个点的概率捏?

yzc提供了一种神奇的办法,考虑对于每个点,先求出每个点的子树的概率和 \(f[u]\)

那么对于一个点 \(u\),就只要让 \(u\) 的所有儿子到他的概率取个并集,

概率并的求法:

\(P(A \cup B)=P(A)+P(B)-P(A)*P(B)\)

第一遍 \(dfs\) 求出所有的 \(f\),但这样只是求出了当前这个点的子树给他充电的概率,还没有求父亲给他充电的概率。

那么再纪录一个 \(g\),数组记录当前的总概率,然后考虑 \(g\) 的转移:

那么我们考虑已经求出了他父亲的 \(g[fa]\) 要求 \(g[v]\)

那么就只要把 当前的点的子树对 \(g[fa]\) 的贡献给除掉就可以了。

求概率补集:

\(P(A)=\frac{P(A \cup B)-P(B)}{1-P(B)}\)\((注意特判1-P(B)==0)\)

那么就可以愉快的用两次 \(dfs\) 求出答案。

#include
using namespace std;typedef double DD;int n,En;DD ans;const int N=5e5+5;inline DD unit(DD a,DD b){ return a+b-a*b;}inline DD split(DD a,DD b){ if(fabs(1.0-b)==0) return 0; return (a-b)/(1.0-b);}DD f[N],g[N],p[N];int head[N];struct edge{ int next,to; DD dis;}E[N<<1];inline void add(int from,int to,DD dis){ E[++En].next=head[from]; E[En].to=to; E[En].dis=dis; head[from]=En;}inline void dfs1(int u,int fa){ f[u]=p[u]; for(int i=head[u];i;i=E[i].next){ int v=E[i].to; if(v==fa) continue; dfs1(v,u); f[u]=unit(f[u],f[v]*E[i].dis); }}inline void dfs2(int u,int fa){ for(int i=head[u];i;i=E[i].next){ int v=E[i].to; if(v==fa) continue; g[v]=unit(f[v],split(g[u],f[v]*E[i].dis)*E[i].dis); dfs2(v,u); }}int main(){ scanf("%d",&n); for(int i=1;i<=n-1;++i){ int u=0,v=0,w=0; scanf("%d%d%d",&u,&v,&w); add(u,v,(DD)w/100); add(v,u,(DD)w/100); } for(int i=1;i<=n;++i){ int x=0; scanf("%d",&x); p[i]=(DD)x/100; } dfs1(1,1); g[1]=f[1]; dfs2(1,1); for(int i=1;i<=n;++i) ans+=g[i]; printf("%.6lf\n",ans); return 0;}

转载于:https://www.cnblogs.com/JCNL666/p/10715777.html

你可能感兴趣的文章
【转】Deep Learning(深度学习)学习笔记整理系列之(二)
查看>>
代码质量与上线压力
查看>>
系统时间不对 导至不能正常上网
查看>>
摄像头说明
查看>>
php 使用 ffmpeg 转换视频,截图,并生成缩略图
查看>>
jQuery EasyUI API 中文文档 - 加载器
查看>>
addedbytes.com 制作的速查表欣赏
查看>>
程序员好难...
查看>>
通过java的Runtime.getRuntime()和System.getProperties()来获取系统的信息
查看>>
Linux对文件归档和压缩(学习笔记八)
查看>>
launch文件概述---1
查看>>
WPF下载远程文件,并显示进度条和百分比
查看>>
实现app上对csdn的文章查看,以及文章中图片的保存 (制作csdn app 完结篇)
查看>>
Linq动态条件
查看>>
大圣归来:我们心中缺少一份英雄主义
查看>>
IIS配置错误信息输出
查看>>
excel使用技巧
查看>>
Flymeos插桩适配教程
查看>>
MySQL备份 博客---MYSQLDBA 黄杉
查看>>
Mysql 修改数据库,mysql修改表类型,Mysql增加表字段,Mysql删除表字段,Mysql修改字段名,Mysql修改字段排列顺序,Mysql修改表名...
查看>>