HDU 4035 期望dp

这道题站在每个位置上都会有三种状态

死亡回到起点:k[i]

找到出口结束 e[i]

原地不动 p[i]

k[i]+e[i]+p[i] =1;

因为只给了n-1条路把所有都连接在一起,那么我们可以自然的把这张图看成一个树型结构

根据作为父亲节点和叶子节点作为区分

进行推导

详情可参考:http://blog.csdn.net/morgan_xww/article/details/6776947/

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 using namespace std;
 5 #define N 10005
 6 #define del 1e-10
 7 vector <int> G[N];
 8 double A[N],B[N],C[N],k[N],e[N],p[N];
 9 int n;
10 bool solve(int u,int fa)
11 {
12     A[u] = k[u];
13     B[u] = p[u] / G[u].size();
14     C[u] = p[u];
15 
16     if(G[u].size() == 1 && fa!=0)
17         return true;
18 
19     double tmp = 0;
20     for(int i=0;i<G[u].size();i++){
21         int j = G[u][i];
22         if(j!=fa)
23         {
24             //既是一个判断过程也是一个找叶子节点的过程,先做递归是为了先更新好叶子节点作为底层的信息,
25             //用以推得上层信息
26             if(!solve(j,u))
27                 return false;
28             A[u]+=B[u]*A[j];
29             C[u]+=B[u]*C[j];
30             tmp +=B[u]*B[j];
31         }
32     }
33 
34     tmp = 1-tmp;
35     if(tmp < del)
36         return false;
37 
38     A[u] /= tmp;
39     B[u] /= tmp;
40     C[u] /= tmp;
41 
42     return true;
43 }
44 
45 int main()
46 {
47     int T,a,b,c,d;
48     scanf("%d",&T);
49     for(int kase=1;kase<=T;kase++){
50         scanf("%d",&n);
51 
52         for(int i=1;i<=n;i++)
53             G[i].clear();
54 
55         for(int i=1;i<n;i++){
56             scanf("%d%d",&a,&b);
57             G[a].push_back(b);
58             G[b].push_back(a);
59         }
60         for(int i=1;i<=n;i++){
61             scanf("%d%d",&c,&d);
62             k[i] = c*1.0/100;
63             e[i] = d*1.0/100;
64             p[i] = 1-k[i]-e[i];
65         }
66 
67         printf("Case %d: ",kase);
68 
69         if(!solve(1,0) || 1-A[1]<del){
70             printf("impossible
");
71             continue;
72         }
73 
74         printf("%.6f
",C[1] / (1-A[1]));
75     }
76 }
原文地址:https://www.cnblogs.com/CSU3901130321/p/3995827.html