HDU 4035 Maze
Maze
http://acm.hdu.edu.cn/showproblem.php?pid=4035
分析:
在树上走来走去,然后在一个点可以k的概率回到1,可以e的概率走出去,可以1-k-e的概率走到其他的位置(分为父节点和子节点讨论)。
转移方程就是:$dp[i] = dp[1] \times k + 0 \times e + \frac{1 - k - e}{deg[i]} \times (dp[fa]+1) + \sum\limits_{j∈child[i]}\frac{1 - k - e}{deg[i]} \times (dp[j]+1)$
发现式子没法转换,有后效性,然后式子只与$dp[1],dp[fa],dp[child[i]]$有关系,可以写成统一的格式:$dp[i] = A_i \times dp[1] +B_i \times dp[fa] +C_i$
这样写完了,发现$A,B,C$就可以从它的子节点转移了,然后可以从叶子节点推到根。最后$dp[1] = \frac{C[1]}{1-A[1]}$。
https://www.cnblogs.com/kuangbin/archive/2012/10/03/2711108.html
代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<cctype> 7 #include<set> 8 #include<vector> 9 #include<queue> 10 #include<map> 11 using namespace std; 12 typedef long long LL; 13 14 inline int read() { 15 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 16 for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 17 } 18 19 const int N = 10010; 20 const double eps = 1e-10; 21 22 double A[N], B[N], C[N], k[N], e[N]; 23 vector<int> T[N]; 24 25 bool dfs(int u,int fa) { 26 double m = 1.0 * T[u].size(); 27 A[u] = k[u], B[u] = (1 - k[u] - e[u]) / m, C[u] = 1 - k[u] - e[u]; 28 double t = 0; 29 for (int i=0; i<m; ++i) { 30 int v = T[u][i]; 31 if (v == fa) continue; 32 if (!dfs(v, u)) return false; 33 A[u] += (1 - k[u] - e[u]) / m * A[v]; 34 C[u] += (1 - k[u] - e[u]) / m * C[v]; 35 t += (1 - k[u] - e[u]) / m * B[v]; 36 } 37 if (fabs(1 - t) <= eps) return false; 38 A[u] /= (1 - t), B[u] /= (1 - t), C[u] /= (1 - t); 39 return true; 40 } 41 42 int main() { 43 for (int Case=read(),t=1; t<=Case; ++t) { 44 int n = read(); 45 for (int i=1; i<=n; ++i) T[i].clear(); 46 for (int i=1; i<n; ++i) { 47 int u = read(), v = read(); 48 T[u].push_back(v), T[v].push_back(u); 49 } 50 for (int i=1; i<=n; ++i) { 51 int a = read(), v = read(); 52 k[i] = (double)a / 100.0; 53 e[i] = (double)v / 100.0; 54 } 55 printf("Case %d: ",t); 56 if (dfs(1, 0) && fabs(A[1] - 1) > eps) 57 printf("%.10lf\n",C[1] / (1 - A[1])); 58 else puts("impossible"); 59 } 60 return 0; 61 }