选个根把无根树转化成有根树,

设f[i]表示i不通电的概率

答案为对于枚举树根root进行DP后1-f[root]的和

直接算是O(n^2)的,但是n有500000,所以不能过。

对于这样一棵以1为根的树,求出它的欧拉遍历序为

1->2->5->2->6->2->1->3->7->3->8->3->1->4->1

可以发现,按照这个序列,每次从上一个转移到下一个时只会在树上移动一步,

父子关系发生变化的也就只有这两个节点,

f[]值会发生变化的也就只有这两个节点。

设之前树根为r,现在准备转移到x上

在r中消去x对它的贡献

在x中加入r对它的贡献

由于是乘法,所以加入贡献只需要

但是消去贡献就不能简单的除法了,因为可能有0

所以需要在每个点多维护

c0[i]表示i的孩子里有几个对它的贡献为0

f2[i]表示i的孩子里不是0的对它贡献的积

对于转移,有两种情况:

1.r是x的父亲:

-消去r对它父亲的贡献

-消去x对它父亲的贡献

-加入r对它父亲的贡献

-加入x对它父亲的贡献

2.x是r的父亲:

-消去r对它父亲的贡献

-加入r对它父亲的贡献

-消去x对它父亲的贡献

-加入x对它父亲的贡献

总时间复杂度$O(n)$

#include<cstdio>
#define N 500010
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
int n,i,x,y,z,g[N],ed,v[N<<1],nxt[N<<1],a[N<<1],eu,root,fa[N],c0[N];
double w[N<<1],q[N],f[N],ans,wf[N],f2[N],eps=1e-8;
bool vis[N];
inline bool is0(double x){return x<eps;}
inline void add(int x,int y,double z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x,int pre){
a[++eu]=x;f[x]=1-q[x];f2[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=pre){
dfs(v[i],x),fa[v[i]]=x,wf[v[i]]=w[i],a[++eu]=x;
double tmp=1-w[i]+w[i]*f[v[i]];
f[x]*=tmp;
if(is0(tmp))c0[x]++;else f2[x]*=tmp;
}
}
inline void delson(int x){
double tmp=1-wf[x]+wf[x]*f[x];
if(is0(tmp))c0[fa[x]]--;else f2[fa[x]]/=tmp;
}
inline void addson(int x){
double tmp=1-wf[x]+wf[x]*f[x];
if(is0(tmp))c0[fa[x]]++;else f2[fa[x]]*=tmp;
}
inline void down(int r,int x){
delson(r);
delson(x);
f[r]=c0[r]?0:(1-q[r])*f2[r]*(1-wf[r]+wf[r]*f[fa[r]]);
addson(r);
f[x]*=1-wf[x]+wf[x]*f[r];
addson(x);
}
inline void up(int r,int x){
delson(r);
f[r]=c0[r]?0:(1-q[r])*f2[r];
addson(r);
delson(x);
f[x]*=1-wf[r]+wf[r]*f[r];
addson(x);
}
int main(){
read(n);
f[0]=1;
for(i=1;i<n;i++)read(x),read(y),read(z),add(x,y,z/100.0),add(y,x,z/100.0);
for(i=1;i<=n;i++)read(z),q[i]=z/100.0;
dfs(1,0);
ans=1-f[root=1];vis[1]=1;
for(i=2;i<=eu;i++){
if(fa[root]==a[i])up(root,a[i]);else down(root,a[i]);
if(!vis[root=a[i]])vis[root]=1,ans+=1-f[root];
}
printf("%.6f",ans);
return 0;
}

  

BZOJ3566 : [SHOI2014]概率充电器的更多相关文章

  1. BZOJ3566 SHOI2014 概率充电器 【概率DP】

    BZOJ3566 SHOI2014 概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能 ...

  2. BZOJ3566: [SHOI2014]概率充电器 树形+概率dp

    3566: [SHOI2014]概率充电器 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1888  Solved: 857[Submit][Stat ...

  3. BZOJ3566 [SHOI2014]概率充电器 (树形DP&概率DP)

    3566: [SHOI2014]概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线能否通电 ...

  4. BZOJ3566:[SHOI2014]概率充电器(树形DP,概率期望)

    Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器: “采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI 概率充电器, ...

  5. BZOJ3566 SHOI2014概率充电器(动态规划+概率期望)

    设f[i]为i在子树内不与充电点连通的概率.则f[i]=(1-pi)·∏(1-qk+qk·f[k]). 然后从父亲更新答案.则f[i]=f[i]·(1-qfa+qfa*f[fa]/(1-qfa+qfa ...

  6. [BZOJ3566][SHOI2014]概率充电器(概率DP)

    题意:树上每个点有概率有电,每条边有概率导电,求每个点能被通到电的概率. 较为套路但不好想的概率DP. 树形DP肯定先只考虑子树,自然的想法是f[i]表示i在只考虑i子树时,能有电的概率,但发现无法转 ...

  7. 2018.08.31 bzoj3566: [SHOI2014]概率充电器(概率dp+容斥原理)

    传送门 概率dp好题啊. 用f[i]" role="presentation" style="position: relative;">f[i] ...

  8. [BZOJ3566][SHOI2014]概率充电器 换根树形DP

    链接 题意:n个充电元件形成一棵树,每个点和每条边都有各自的充电概率,元件可以自身充电或者通过其他点和边间接充电,求充电状态元件的期望个数 题解 设1为根节点 设 \(f[x]\) 表示 \(x\) ...

  9. 【BZOJ3566】[SHOI2014]概率充电器 期望+树形DP

    [BZOJ3566][SHOI2014]概率充电器 Description 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品——概率充电器:“采用全新纳米级加工技术,实现元件与导线 ...

随机推荐

  1. poj1611(并查集)

    题目链接:http://poj.org/problem?id=1611 题意: SARS(非典型肺炎)传播得非常厉害,其中最有效的办法是隔离那些患病.和患病者接触的人.现在有几个学习小组,每小组有几个 ...

  2. 3.2 STL中的函数对象类模板

    *: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...

  3. case/casez/casex 的区分与使用

    参考:http://www.cnblogs.com/poiu-elab/archive/2012/11/02/2751323.html 与  verilog数字系统设计基础 一般来说,使用最多的是CA ...

  4. OpenCv,EmguCv及.net之间的互动(The Interaction of OpenCv, EmguCv AND .net)

    http://www.cnblogs.com/xrwang/archive/2010/01/26/TheInteractionOfOpenCv-EmguCvANDDotNet.html 前言 在.ne ...

  5. Python中判断是否为闰年,求输入日期是该年第几天

    #coding = utf-8 def getLastDay(): y = int(input("Please input year :")) m = int(input(&quo ...

  6. CLR via C#(15)--String,熟悉而又陌生

    好久没写文章了,再拿起这本书,学习加分享,乐趣无穷啊.这两天看了写关于字符串的知识,从学写代码的时候开始,我们就基本天天跟String打交道,对它再熟悉不过了.但是仔细看看,还是有一种拨开云雾的感觉, ...

  7. Android 下拉刷新

    以前旧版用的是开源的PullToRefresh第三方库,该库现在已经不再维护了: chrisbanes/Android-PullToRefreshhttps://github.com/chrisban ...

  8. Delphi测试线程的时间

    在16位时代,当我们在Windows3.x下编程时,经常会用到GetTickCount()或者timeGetTime()来判断一段代码的执行时间.示例如下 var StartTime, Total: ...

  9. 一个通过网络转换Ico到Png图片的小小程序(Ico2Png)

    做软件界面需要用到ico文件, 结果皮肤库不支持ico格式的图标, 所以就想到了把ico转换成png. 网上ico转png的软件貌似并不多, 反倒是png转ico很大一片~~~~~~~~~ 要转换ic ...

  10. Metrics介绍

    Metrics可以为你的代码的运行提供无与伦比的洞察力.作为一款监控指标的度量类库,它提供了很多模块可以为第三方库或者应用提供辅助统计信息, 比如Jetty, Logback, Log4j, Apac ...