Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4035
Probability DP on the tree.
|
MazeTime Limit: 2000/1000 MS (Java/others) memory limit: 65768/65768 K (Java/others) total submission (s): 1626 accepted submission (s): 608 Special JudgeProblem descriptionwhen wake up, lxhgww find himself in a huge maze. The maze consisted by N rooms and tunnels connecting these rooms. each pair of rooms is connected by one and only one path. initially, lxhgww is in room 1. each room has a dangerous trap. when lxhgww step into a room, he has a possibility to be killed and restart from Room 1. every room also has a hidden exit. each time lxhgww comes to a room, he has chance to find the exit and escape from this maze. Unfortunately, lxhgww has no idea about the structure of the whole maze. therefore, he just chooses a tunnel randomly each time. when he is in a room, he has the same possibility to choose any tunnel connecting that room (including the tunnel he used to come to that room ). what is the maximum CT number of tunnels he go through before he find the exit? Inputfirst line is an integer T (T ≤ 30), the number of test cases. At the beginning of each case is an integer N (2 ≤ n ≤ 10000), indicates the number of rooms in this case. Then N-1 pairs of integers x, y (1 ≤ x, y ≤ n, x = y) are given, indicate there is a tunnel between room X and room y. Finally, N pairs of integers KI and EI (0 ≤ Ki, EI ≤ 100, Ki + EI ≤ 100, k1 = e1 = 0) are given, indicate the percent of the possibility of been killed and exit in the ith room. outputfor each test case, output one line "case K :". K is the case ID, then the exact CT number of tunnels lxhgww go through before he exit. the answer with relative error less than 0.0001 will get accepted. if it is not possible to escape from the maze, output "impossible ". sample input331 21 30 0100 00 10031 22 30 0100 00 10061 22 31 44 54 60 020 3040 3050 5070 60 sample outputcase 1: 1020 Case 2: impossiblecase 3: 2.000000 |
Http://www.cnblogs.com/kuangbin/archive/2012/10/03/2711108.html
Niu Ren's blog ideas
DP to find the expected question. There are n rooms connected by n-1 tunnels. In fact, a tree is formed. Starting from node 1, there are three possibilities at each node I: 1. killed, return to node 1 (probability is Ki) 2. find the exit and exit the maze (probability is EI). 3. there are m edges connected to the point, and a random result is taken: the expected value of the number of edges to be taken out of the maze. Set E [I] to represent the expected number of edges to walk out of the maze at node I. E [1] is the request. Leaf node: E [I] = Ki * E [1] + EI * 0 + (1-ei EI) * (E [Father [I] + 1 ); = Ki * E [1] + (1-0000ei) * E [Father [I] + (1-0000ei); Non-leaf node: (m is the number of edges connected to the node) E [I] = Ki * E [1] + EI * 0 + (1-ei EI) /M * (E [Father [I] + 1 + Σ (E [child [I] + 1); = Ki * E [1] + (1-127ei) /M * E [Father [I] + (1-0000ei)/m * Σ (E [child [I]) + (1-0000ei); set each node: E [I] = ai * E [1] + bi * E [Father [I] + ci; for non-leaf node I, set J to the 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 the formula above (1-(1-ei EI)/m * Σ BJ) * E [I] = (KI + (1-0000ei)/m * Σ AJ) * E [1] + (1-0000ei) /M * E [Father [I] + (1-0000ei) + (1-0000ei)/m * Σ CJ; thus, AI = (KI + (1-0000ei)/m * Σ AJ) can be obtained) /(1-(1-0000ei)/m * Σ BJ); Bi = (1-0000ei)/M/(1-(1-0000ei)/m * Σ BJ ); ci = (1-digit EI) + (1-digit EI)/m * Sigma CJ)/(1-(1-digit EI)/m * Sigma BJ); for leaf node AI = Ki; bi = 1-ki-EI; CI = 1-ki-EI; Starting from the leaf node until A1, B1, and c1 are calculated; E [1] = A1 * E [1] + B1 * 0 + C1; so E [1] = C1/(1-A1 ); if A1 approaches 1, there is no solution...
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int len,head[10005];double A,B,C;double k[10005],e[10005];struct node{ int now,next;}tree[20005];void add(int x,int y){ tree[len].now=y; tree[len].next=head[x]; head[x]=len++;}void dfs(int root,int p){ int i,son,m=0; double a=0,b=0,c=0,q; for(i=head[root];i!=-1;i=tree[i].next) { son=tree[i].now; if(son==p) { continue; } dfs(son,root); a+=A; b+=B; c+=C; m++; } if(p != -1)++m; q=(1-k[root]-e[root])/m; A=(k[root]+q*a)/(1-q*b); B=q/(1-q*b); C=(1-k[root]-e[root]+q*c)/(1-q*b);}int main(){ int t,n,a,b,j,i; int x,y; scanf("%d",&t); for(j=1;j<=t;j++) { len=0; memset(head,-1,sizeof(head)); memset(e,0,sizeof(e)); memset(k,0,sizeof(k)); scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } for(i=1;i<=n;i++) { scanf("%d%d",&x,&y); // printf("x=%d,y=%d\n",x,y); k[i]=x/100.0; e[i]=y/100.0; // printf("k[i]=%lf,e[i]=%lf\n",k[i],e[i]); } dfs(1,-1); if(1-A<1e-9) printf("Case %d: impossible\n",j); else printf("Case %d: %lf\n",j,C/(1-A)); } return 0;}