HDU4035 Maze 【树形DP】【期望DP】

题目分析:

以前一直不会这个方法, 我好菜啊。

转移分为三个部分,一个是直接成功,一个是转移到E1,还有一个是转移到自己周围的一圈儿点。 如果是叶子那么只能转移到父亲,如果不是叶子可以把非叶子的转移代换,这样也只转移到父亲,判一下无解就行了。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 10200;
 5 const double eps = 1e-10;
 6 
 7 int n,Tmp,cas;
 8 double a[maxn],b[maxn];
 9 vector<int> g[maxn];
10 
11 double A[maxn],B[maxn],C[maxn];
12 
13 void dfs(int now,int f){
14     int cnt = 0;
15     for(int i=0;i<g[now].size();i++){
16     if(g[now][i] == f) continue;
17     cnt++; dfs(g[now][i],now);
18     }
19     if(cnt == 0){A[now] = a[now]; B[now] = 1-a[now]-b[now]; C[now] = B[now];}
20     else{
21     double alpha = 0,beta = 0,gamma = 0;
22     for(int i=0;i<g[now].size();i++){
23         if(g[now][i] == f) continue;
24         alpha += A[g[now][i]];beta += B[g[now][i]];gamma += C[g[now][i]];
25     }
26     if(f != 0){
27         gamma += cnt+1;
28         alpha *= (1-a[now]-b[now])/(cnt+1);
29         beta *= (1-a[now]-b[now])/(cnt+1);
30         gamma *= (1-a[now]-b[now])/(cnt+1);
31         B[now] = (1-a[now]-b[now])/(cnt+1);
32         beta = 1-beta; C[now] = gamma; A[now] = alpha+a[now];
33         C[now] /= beta; A[now] /= beta; B[now] /= beta;
34     }else{
35         gamma += cnt;
36         alpha *= (1-a[now]-b[now])/cnt;
37         beta *= (1-a[now]-b[now])/cnt;
38         gamma *= (1-a[now]-b[now])/cnt;
39         B[now] = 0; C[now] = gamma; beta = 1-(alpha+beta+a[now]);
40         if(beta <= eps){C[now] = -1;}
41         else C[now] /= beta;
42     }
43     }
44 }
45 
46 void read(){
47     scanf("%d",&n);
48     memset(A,0,sizeof(A));
49     memset(B,0,sizeof(B));
50     memset(C,0,sizeof(C));
51     memset(a,0,sizeof(a));
52     memset(b,0,sizeof(b));
53     for(int i=1;i<=n;i++) g[i].clear();
54     for(int i=1;i<n;i++){
55     int u,v; scanf("%d%d",&u,&v);
56     g[u].push_back(v); g[v].push_back(u);
57     }
58     for(int i=1;i<=n;i++) {
59     int u,v; scanf("%d%d",&u,&v);
60     a[i] = u/100.0,b[i] = v/100.0;
61     }
62 }
63 
64 void work(){
65     dfs(1,0);
66     printf("Case %d: ",cas);
67     if(C[1] == -1){puts("impossible");}
68     else{printf("%.6lf
",C[1]);}
69 }
70 
71 int main(){
72     scanf("%d",&Tmp);
73     while(cas++,Tmp--){
74     read();
75     work();
76     }
77     return 0;
78 }