Case 3: 2.895522
设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望。E[1]即为所求。
叶子结点:
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);
非叶子结点:(m为与结点相连的边数)
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);
设对每个结点:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;
对于非叶子结点i,设j为i的孩子结点,则
∑(E[child[i]]) = ∑E[j]
= ∑(Aj*E[1] + Bj*E[father[j]] + Cj)
= ∑(Aj*E[1] + Bj*E[i] + Cj)
带入上面的式子得
(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;
由此可得
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);
对于叶子结点
Ai = ki;
Bi = 1 - ki - ei;
Ci = 1 - ki - ei;
从叶子结点开始,直到算出 A1,B1,C1;
E[1] = A1*E[1] + B1*0 + C1;
所以
E[1] = C1 / (1 - A1);
若 A1趋近于1则无解...
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <vector> using namespace std; #define eps 1e-9 #define M 100500 double a[M],b[M],c[M],x[M],k[M],p[M],m[M],e[M]; vector<int > vec[M]; int dfs(int now,int pre){ m[now]=vec[now].size(); if(vec[now].size()==1){ a[now]=k[now];b[now]=1-k[now]-e[now];c[now]=1-k[now]-e[now]; //return 1; } x[now]=(1-k[now]-e[now])/m[now]; double tempb=0,tempa=0,tempc=0; for(int i=0;i<vec[now].size();i++){ int j=vec[now][i]; if(j==pre)continue; if(!dfs(j,now))return false; tempa+=a[j],tempb+=b[j],tempc+=c[j]; } double tmpk=(1-x[now]*tempb); if(fabs(tmpk)<eps)return 0; a[now]=(k[now]+x[now]*tempa)/tmpk; b[now]=x[now]/tmpk; c[now]=(1-k[now]-e[now]+x[now]*tempc)/tmpk; return 1; } int main() { int tcase,i,ss,ee,tt=1,n; scanf("%d",&tcase); while(tcase--){ scanf("%d",&n); for(i=0;i<=n;i++) vec[i].clear(); for(i=1;i<n;i++){ scanf("%d%d",&ss,&ee); vec[ee].push_back(ss); vec[ss].push_back(ee); } for(i=1;i<=n;i++){ scanf("%lf%lf",&k[i],&e[i]); k[i]/=100.0;e[i]/=100.0; } if(dfs(1,-1)&&(1-a[1])>eps){ printf("Case %d: %.6f\n",tt++,c[1]/(1.0-a[1])); } else printf("Case %d: impossible\n",tt++); } return 0; }