这道题站在每个位置上都会有三种状态
死亡回到起点: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 }