The game looked at the problem, but there was no train of thought. After the game after the total through the 20+, after the game to see the problem-solving report, because the blogger said too concise, and I have never seen this DP seeking mathematical expectations of the problem, so studied for a long time wood has clear. Only search for "DP for expectations" of the topic, starting from a simple start, the eldest brother Kung Fu, finally understand, so write a detailed problem solving report.
If you don't understand the problem, you can follow my steps: Poj 2096---Zoj 3329--Hdu 4035
/** DP to ask for the desired problem.
Test instructions: There are n rooms, connected by the N-1 tunnel, actually formed a tree, starting from Node 1, start walking, at each node I have 3 possible: 1. Be killed, return to Node 1 (probability of Ki) 2. Find exit and get out of the maze (probability is EI)
3. And the point is connected with M-bar, randomly walk a request: Out of the maze of the number of sides to go to the expected value. Set E[i] Indicates the expectation of the number of sides to go out of the maze at node I.
E[1] is the request.
Leaf node: e[i] = ki*e[1] + ei*0 + (1-ki-ei) * (E[father[i]] + 1);
= Ki*e[1] + (1-ki-ei) *e[father[i]] + (1-KI-EI);
Non-leaf nodes: (M is the number of sides connected to the node) e[i] = ki*e[1] + ei*0 + (1-ki-ei)/m* (e[father[i]]+1 +∑ (e[child[i]]+1));
= Ki*e[1] + (1-ki-ei)/m*e[father[i] + (1-ki-ei)/m*∑ (E[child[i]]) + (1-KI-EI);
Set to each node: e[i] = ai*e[1] + bi*e[father[i] + Ci;
For non-leaf node I, set J for child node of I, then ∑ (E[child[i]]) =∑e[j] =∑ (aj*e[1] + bj*e[father[j] + Cj) =∑ (Aj*e[1] + bj*e[i] + Cj) bring in the above formula (1-(1-ki-ei)/m*∑bj) *e[i] = (ki+ (1-ki-ei)/m*∑aj) *e[1] + (1-ki-ei)/m*e[father
[i]] + (1-ki-ei) + (1-ki-ei)/M*∑CJ;
This is an Ai = (ki+ (1-ki-ei)/m*∑aj)/(1-(1-ki-ei)/M*∑BJ); Bi =(1-ki-ei)/M/(1-(1-ki-ei)/M*∑BJ);
Ci = ((1-ki-ei) + (1-ki-ei)/M*∑CJ)/(1-(1-ki-ei)/M*∑BJ);
For the leaf node Ai = ki;
Bi = 1-ki-ei;
Ci = 1-ki-ei;
Start from the leaf node until the a1,b1,c1 is calculated;
E[1] = a1*e[1] + b1*0 + C1;
So e[1] = C1/(1-A1); If A1 is approaching 1, no solution ... **/#include <cstdio> #include <iostream> #include <vector> #include <cmath> usin
G namespace Std;
const int MAXN = 10000 + 5;
Double E[MAXN], K[MAXN];
Double A[MAXN], B[MAXN], C[MAXN];
Vector<int> V[MAXN];
BOOL Search (int i, int fa) {if (v[i].size () = = 1 && fa! = 1) {A[i] = K[i];
B[i] = 1-k[i]-e[i];
C[i] = 1-k[i]-e[i];
return true;
} A[i] = K[i];
B[i] = (1-k[i]-e[i])/v[i].size ();
C[i] = 1-k[i]-e[i];
Double tmp = 0;
for (int j = 0; J < (int) v[i].size (); j + +) {if (v[i][j] = = FA) continue; if (!search (v[i][j], i)) return false;
A[i] + = A[v[i][j]] * b[i];
C[i] + = C[v[i][j]] * b[i];
TMP + = B[v[i][j]] * b[i];
} if (Fabs (tmp-1) < 1e-10) return false;
A[i]/= 1-tmp;
B[i]/= 1-tmp;
C[i]/= 1-tmp;
return true;
} int main () {int NC, n, s, t;
CIN >> NC;
for (int CA = 1; CA <= NC; ca++) {cin >> n;
for (int i = 1; I <= n; i++) v[i].clear ();
for (int i = 1; i < n; i++) {cin >> s >> t;
V[s].push_back (t);
V[t].push_back (s);
} for (int i = 1; I <= n; i++) {cin >> k[i] >> e[i];
K[i]/= 100.0;
E[i]/= 100.0;
} cout << "case" << CA << ":";
if (search (1,-1) && fabs (1-a[1]) > 1e-10) cout << c[1]/(1-a[1]) << Endl; else cout << "impossible" << Endl;
} return 0;
}