著名的电子产品品牌 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%。
输出一行一个实数,为进入充电状态的元件个数的期望,四舍五入到六位小数
对于 100%的数据,n≤500000,0≤p,qi≤100。
1 /*by SilverN*/
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdio>
6 #include<cmath>
7 #include<vector>
8 using namespace std;
9 const int mxn=500010;
10 int read(){
11 int x=0,f=1;char ch=getchar();
12 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
13 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
14 return x*f;
15 }
16 struct edge{
17 int v,nxt;
18 double w;
19 }e[mxn<<1];
20 int hd[mxn],mct=0;
21 int w[mxn];
22 double f[mxn],g[mxn];//不从子树充电的概率,不向上贡献的概率
23 double dp[mxn];//不从父亲充电的概率
24 void add_edge(int u,int v,double w){
25 e[++mct].nxt=hd[u];e[mct].v=v;e[mct].w=w;hd[u]=mct;return;
26 }
27 void DP(int u,int fa,int id){//自底向上的贡献
28 f[u]=1-w[u]/(double)100.0;//自己没电的概率
29 for(int i=hd[u],v;i;i=e[i].nxt){
30 if(e[i].v==fa)continue;
31 v=e[i].v;
32 DP(v,u,i);
33 f[u]*=g[v];
34 }
35 g[u]=f[u]+(1.0-f[u])*(1.0-e[id].w);
36 // printf("f[%d]:%.3f g[%d]:%.3f\n",u,f[u],u,g[u]);
37 return;
38 }
39 void PD(int u,int fa){//自顶向下的贡献
40 for(int i=hd[u],v;i;i=e[i].nxt){
41 if(e[i].v==fa)continue;
42 v=e[i].v;
43 double x;
44 if(g[v]<1e-6)x=0;
45 else x=f[u]*dp[u]/g[v];
46 dp[v]=x+(1-x)*(1-e[i].w);
47 PD(v,u);
48 }
49 return;
50 }
51 int n;
52 double ans=0;
53 int main(){
54 int i,j;
55 n=read();
56 int a,b,p;
57 for(i=1;i<n;i++){
58 a=read();b=read();p=read();
59 add_edge(a,b,p/(double)100.0);
60 add_edge(b,a,p/(double)100.0);
61 }
62 for(i=1;i<=n;i++)w[i]=read();
63 DP(1,0,0);
64 dp[1]=1;
65 PD(1,0);
66 for(i=1;i<=n;i++)ans+=1-f[i]*dp[i];
67 printf("%.6lf\n",ans);
68 return 0;
69 }