bzoj3566 probability charger [tree expected probability dp]

Solutions:

A node is either charged by the father or by the son or himself.
We find that it's a bit troublesome to calculate the probability of charging with probability addition, so we can calculate the probability that a point can't be charged with electricity, that is, no source can have electricity, and the probability can be multiplied directly.

Let f[i] denote the probability that son[i] can't charge and can't charge himself directly;
Let g[i] denote the probability that the father will not be able to power up.
Let h[i] denote the probability that I can't charge the father, either I can't, or (i,fa[i]) is off.

that
h[i]=f[i]+(1−f[i])∗(1−p(i,fa[i]))
f[i]=(1−q[i])∗Πf[son[i]]

Charging from the father may be from the father chain, from the brother through the father, or (i,fa[i]) disconnection.
t=g[fa[i]] * f[fa[i]]h[i].
So g[i]=t+(1 − t) * 1 − p(i,fa[i]).

We can find f[i],h[i] by dfs and g[i] by dfs.

The answer is Σ 1 − f[i] * g[i]

#include<bits/stdc++.h>
using namespace std;

int getint()
{
    int i=0,f=1;char c;
    for(c=getchar();(c!='-')&&(c<'0'||c>'9');c=getchar());
    if(c=='-')f=-1,c=getchar();
    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
    return i*f;
}

const int N=500005;
const double eps=1e-8;
int n,tot,first[N],nxt[N<<1],to[N<<1];
double ans,f[N],g[N],h[N],q[N],p[N<<1];

void add(int x,int y,double z)
{
    nxt[++tot]=first[x],first[x]=tot,to[tot]=y,p[tot]=z;
}

void dfs1(int u,int fa)
{
    f[u]=1-q[u];
    for(int e=first[u];e;e=nxt[e])
    {
        int v=to[e];
        if(v==fa)continue;
        dfs1(v,u);
        h[v]=f[v]+(1-f[v])*(1-p[e]);
        f[u]*=h[v];
    }
}

void dfs2(int u,int fa)
{
    for(int e=first[u];e;e=nxt[e])
    {
        int v=to[e];
        if(v==fa)continue;
        double t=h[v]<eps?0:g[u]*f[u]/h[v];
        g[v]=t+(1-t)*(1-p[e]);
        dfs2(v,u);
    }
}

int main()
{
    //freopen("lx.in","r",stdin);
    int x,y;double z;
    n=getint();
    for(int i=1;i<n;i++)
    {
        x=getint(),y=getint(),z=getint()*1.0/100;
        add(x,y,z),add(y,x,z);
    }
    for(int i=1;i<=n;i++)q[i]=getint()*1.0/100;
    dfs1(1,0);
    g[1]=1,dfs2(1,0);
    for(int i=1;i<=n;i++)ans+=1-f[i]*g[i];
    printf("%.6f",ans);
    return 0;
}

Posted by yapyapayap on Sat, 02 May 2020 03:08:29 -0700