HDU 4035期待dp
10340 ワード
この問題は位置ごとに3つの状態がある.
死は起点に戻る:k[i]
出口を見つけて終了e[i]
その場で動かないp[i]
k[i]+e[i]+p[i] =1;
n-1本の道だけがすべてをつなぐので、自然にこの図を木の構造と見ることができます.
親ノードとして葉ノードとして区別する
導き出す
詳細は、http://blog.csdn.net/morgan_xww/article/details/6776947/を参照してください.
死は起点に戻る: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 }