hdu 4035 Maze

题意:

有n个房间,这n个房间通过n-1条边相连,形如一棵树。

一个人走进一个房间,有ki概率被杀死,在1号房间复活;有ei概率逃走。

问逃走经过的边数的期望时多少。

思路:

概率dp。借鉴了这位前辈的思路:https://blog.csdn.net/morgan_xww/article/details/6776947/。

还有一点树形dp的思想在里面。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <vector>
 5 #include <math.h>
 6 using namespace std;
 7 const int N = 1e4 + 10;
 8 double a[N],b[N],c[N],k[N],e[N];
 9 vector<int> g[N];
10 void dfs(int u,int fa)
11 {
12     int m = 0;
13     double A = 0,B = 0,C = 0;
14     for (int v:g[u])
15     {
16         if (v != fa)
17         {
18             m++;
19             dfs(v,u);
20             A += a[v];
21             B += b[v];
22             C += c[v];
23         }
24     }
25     if (m == 0)
26     {
27         a[u] = k[u];
28         b[u] = 1 - k[u] - e[u];
29         c[u] = 1 - k[u] - e[u];
30         return;
31     }
32     if (u != 1) m++;
33     a[u] = (k[u] + (1-k[u]-e[u])/m*A) / (1-(1-k[u]-e[u])/m*B);
34     b[u] = (1-k[u]-e[u]) / m / (1-(1-k[u]-e[u])/m*B);
35     c[u] = ((1-k[u]-e[u]) + (1-k[u]-e[u])/m*C) / (1-(1-k[u]-e[u])/m*B);
36 }
37 int main()
38 {
39     int T;
40     scanf("%d",&T);
41     int kase = 0;
42     while (T--)
43     {
44         int n;
45         scanf("%d",&n);
46         for (int i = 1;i <= n;i++) g[i].clear();
47         for (int i = 1;i < n;i++)
48         {
49             int x,y;
50             scanf("%d%d",&x,&y);
51             g[x].push_back(y);
52             g[y].push_back(x);
53         }
54         for (int i = 1;i <= n;i++)
55         {
56             scanf("%lf%lf",&k[i],&e[i]);
57             k[i] /= 100.0;
58             e[i] /= 100.0;
59         }
60         dfs(1,-1);
61         printf("Case %d: ",++kase);
62         if (fabs(1-a[1]) < 1e-10)
63         {
64             puts("impossible");
65         }
66         else
67         {
68             printf("%.8f\n",c[1] / (1-a[1]));
69         }
70     }
71     return 0;
72 }

 

posted @ 2018-05-07 21:49  qrfkickit  阅读(173)  评论(0编辑  收藏  举报