版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/88183226
题目
这个题。。。
如果我们只考虑从儿子到父亲的传输电,之后可以再用一个dfs从上至下更新父亲对儿子的贡献。
但是这个题需要求的是概率而非期望(直接算期望不好求),就没有那些什么线性性:
注意对于第二个式子,Claris大佬认为会除0,于是还存了当前的概率上有几个0,但其实是不需要的,如果
,那么。。。下面是一定会通电的,直接赋值
就行
#include<bits/stdc++.h>
#define maxn 500005
#define double long double
using namespace std;
int n;
int info[maxn],Prev[maxn<<1],to[maxn<<1],cnt_e;
double cst[maxn<<1];
inline void Node(int u,int v,double ct){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=ct; }
double zc[maxn];
double dp[maxn];
void dfs(int now,int ff)
{
dp[now] = zc[now];
for(int i=info[now];i;i=Prev[i])
if(to[i]!=ff)
{
dfs(to[i],now);
double tmp = dp[to[i]] * cst[i];
dp[now] = dp[now] + tmp - dp[now] * tmp;
}
}
double dp2[maxn],ans;
void ser(int now,int ff)
{
ans +=dp2[now];
for(int i=info[now];i;i=Prev[i])
if(to[i]!=ff)
{
double tmp = dp[to[i]] * cst[i];
if(fabs(tmp - 1)<1e-8) dp2[to[i]] = 1;
else
{
double pfa = (dp2[now]-tmp)/(1-tmp)*cst[i];
dp2[to[i]] = dp[to[i]] + pfa - pfa * dp[to[i]];
}
ser(to[i],now);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u,v,p;
scanf("%d%d%d",&u,&v,&p);
Node(u,v,p/100.0),Node(v,u,p/100.0);
}
for(int i=1;i<=n;i++) scanf("%Lf",&zc[i]),zc[i]/=100;
dfs(1,0);
dp2[1] = dp[1];
ser(1,0);
printf("%.6Lf",ans);
}