HDU 4035 Maze(树形概率DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4035

题意:一棵树,从结点1出发,在每个结点 i 都有3种可能:(1)回到结点1 , 概率 Ki;(2)结束,概率 Ei;(3)随机走一条边。(Ki+Ei+随机走=1) 求到结束需要走的边数的期望。

思路:设Q[i]表示从i到结束的期望,设Q[i]=A[i]*Q[1]+B[i]*Q[fa[i]]+C[i]。

对于叶子节点,Q[i]=K[i]*Q[1]+E[i]*0+(1-K[i]-E[i])*(Q[fa[i]]+1),

对于叶子节点那么我们可得到:A[i]=K[i],B[i]=1-K[i]-E[i],C[i]=1-K[i]-E[i]。

对于非叶子节点,设与其相连的点有m个,则到每个点的概率都是temp=(1-K[i]-E[i])/m,Q[i]=K[i]*Q[1]+E[i]*0+temp*(Q[fa[i]]+Q[son[1]]+Q[son[2]+……Q[son[m-1]]]+1)。

计算出其子节点带入得到:令X=1-temp*sum(B[son[i]]),

A[i]=(K[i]+temp*sum(A[son[i]]))/X

B[i]=(1-K[i]-E[i])/m/X

C[i]=(1-K[i]-E[i]+temp*sum(C[son[i]]))/X

那么无解有两种情况:(1)中间计算过程出现X=0;(2)Q[1]=A[1]*Q[1]+B[1]+C[1],A[1]=1。



double A[N],B[N],C[N],K[N],E[N];
vector<int> g[N];
int n;

int flag;

void DFS(int u,int pre)
{
    A[u]=K[u];
    B[u]=(1-K[u]-E[u])/SZ(g[u]);
    C[u]=1-K[u]-E[u];
    int i,v;
    double temp=(1-K[u]-E[u])/SZ(g[u]),x=1;
    FOR0(i,SZ(g[u]))
    {
        v=g[u][i];
        if(v==pre) continue;
        DFS(v,u);
        A[u]+=temp*A[v];
        x-=temp*B[v];
        C[u]+=temp*C[v];
    }
    if(fabs(x)<EPS) flag=1;
    else A[u]/=x,B[u]/=x,C[u]/=x;
}


int main()
{
    int num=0;
    rush()
    {
        RD(n);
        int i,u,v;
        FOR1(i,n) g[i].clear();
        FOR1(i,n-1)
        {
            RD(u,v);
            g[u].pb(v);
            g[v].pb(u);
        }
        FOR1(i,n) RD(K[i],E[i]),K[i]/=100,E[i]/=100;
        flag=0;
        DFS(1,-1);
        printf("Case %d: ",++num);
        if(fabs(A[1]-1)<EPS||flag) puts("impossible");
        else PR(C[1]/(1-A[1]));
    }
    return 0;
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值