zoukankan      html  css  js  c++  java
  • 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) 求到结束需要走的边数的期望。

    假设E[i]为点i到结束走边数的期望,则有

    (以下m为点的度数)

    E[i]=ki*E[1]+(1-ei-ki)/m*(E[fa[i]]+1)若i为叶子节点.

    =ki*E(1)+(1-ki-ei)*E(father)+(1-ki-ei) 

    E[i]=ki*E[1]+(1-ei-ki)/m*(E[fa[i]]+1)+(1-ei-ki)/m*(Sum(E[son[i]]+1))i不为叶子节点

    =ki*E(1)+(1-ki-ei)/m *E(father)+(1-ki-ei)/m*SUM(E(child))+(1-ki-ei)  作为1式

    我们发现,这样求非常麻烦,若是n小一点大可用高斯消元求解,可这题的n为10000,无法用高斯消元。

    对于每个E[i],我们令E[i]=Ai*(E[1])+Bi*(E[fa[i]])+Ci

    E[child]=Aj*E[1]+Bj*E[i]+Cj

    Sum(E[child])=Sum(Aj*E[1]+Bj*E[i]+Cj)

    带入1式:ki*E(1)+(1-ki-ei)/m *E(father)+(1-ki-ei)/m*Sum(Aj*E[1]+Bj*E[i]+Cj)+(1-ki-ei)

    可得:(ki+(1-ki-ei)/m*SUM(Aj))*E(1)+(1-ki-ei)/m *E(father)+(1-ki-ei+(1-ki-ei)/m*SUM(cj))

    与刚才的E[i]=Ai*(E[1])+Bi*(E[fa[i]])+Ci对比一下发现:

    Ai=(ki+(1-ki-ei)/m*SUM(Aj))

    Bi=(1-ki-ei)/m 

    Ci=(1-ki-ei+(1-ki-ei)/m*SUM(cj))

    对于叶子节点,有

    Ai=ki

    Bi=1-ki-ei

    Ci=1-ki-ei

    倒推即可,还有,

    E(1)=A1*E(1)+B1*0+C1

    E(1)=C1/(1-A1)

    若是上述式子中的分母出现0则无解。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<algorithm>
     6 const double eps=1e-9;
     7 int tot,go[500005],first[500005],next[500005];
     8 double a[500005],b[500005],c[500005],k[500005],e[500005];
     9 int n,du[500005];
    10 void insert(int x,int y){tot++;go[tot]=y;next[tot]=first[x];first[x]=tot;}
    11 void add(int x,int y){insert(x,y);insert(y,x);}
    12 bool dfs(int x,int fa){
    13     bool Isleave=1;
    14     double tmp=0;
    15     a[x]=k[x];
    16     b[x]=c[x]=(1-k[x]-e[x]);
    17     b[x]/=du[x];
    18     for (int i=first[x];i;i=next[i]){
    19         int pur=go[i];
    20         if (pur==fa) continue;
    21         Isleave=0;
    22         if (!dfs(pur,x)) return false;
    23         a[x]+=a[pur]*(1-k[x]-e[x])/du[x];
    24         c[x]+=c[pur]*(1-k[x]-e[x])/du[x];
    25         tmp+=(b[pur])*(1-k[x]-e[x])/du[x];
    26     }
    27     if (fabs(tmp-1)<=eps) return false;
    28     a[x]/=(1-tmp);
    29     b[x]/=(1-tmp);
    30     c[x]/=(1-tmp);
    31     return true;
    32 }
    33 int main(){
    34     int T,Tcase=0;
    35     scanf("%d",&T);
    36     while (T--){
    37         Tcase++;
    38         tot=0;
    39         memset(first,0,sizeof first);
    40         memset(du,0,sizeof du);
    41         scanf("%d",&n);
    42         for (int i=1;i<n;i++){
    43             int x,y;
    44             scanf("%d%d",&x,&y);
    45             add(x,y);
    46             du[x]++;
    47             du[y]++;
    48         }
    49         for (int i=1;i<=n;i++){
    50             scanf("%lf%lf",&k[i],&e[i]);
    51             k[i]/=100;e[i]/=100;
    52         }
    53         printf("Case %d: ",Tcase);
    54         if (dfs(1,0)&&fabs(1-a[1])>eps){
    55             printf("%.6f
    ",c[1]/(1-a[1]));
    56         }
    57         else{
    58             printf("impossible
    ");
    59         }
    60     }
    61 }
  • 相关阅读:
    web-----------HTTP协议
    python基础作业------模拟实现一个ATM + 购物商城程序
    python--------进程与线程
    作业--用户输入数字0-100,判断成绩,用函数
    blog真正的首页
    blog首页视图
    让django完成翻译,迁移数据库模型
    创建Django博客的数据库模型
    创建blog APP
    在PyCharm上创建Django项目
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5543901.html
Copyright © 2011-2022 走看看