解题报告链接:
http://www.cnblogs.com/kuangbin/archive/2012/10/03/2711108.html
先推公式,设计状态,令DP[i]表示在房间i退出要走步数的期望值,然后推导出关系式,亮点来了,不会搜索···
so,等我学会了搜索后明天再写····
哈哈,已经学会了,自己设计的,和解题报告的不太一样,一个DFS解决···
看代码吧···我不知道怎么说····
贴代码:
1 //#define debug 2 #include <cstdio> 3 #include <vector> 4 #include <cmath> 5 #define N 10005 6 #define eps 1e-10 7 using namespace std; 8 vector<int> ve[N]; 9 struct node 10 { 11 double ki,wal; 12 } p[N]; 13 struct para 14 { 15 double a,b,c; 16 }; 17 int n; 18 bool vis[N]; 19 para dfs(int x) 20 { 21 vis[x] = 1; 22 bool flag = true; 23 para t,t1,t2; 24 //t1用来求sum(j),其中j为x的子节点 25 t1.a = 0; 26 t1.b =0; 27 t1.c = 0; 28 for(int i=0; i<ve[x].size(); ++i) 29 { 30 if(!vis[ve[x][i]]) 31 { 32 flag =false; 33 t2 = dfs(ve[x][i]); 34 t1.a += t2.a; 35 t1.b += t2.b; 36 t1.c += t2.c; 37 } 38 } 39 // 对于非叶子节点:j为i的子节点 40 // Ai = (ki+(1-ki-ei)/m*∑Aj) / (1 - (1-ki-ei)/m*∑Bj); 41 // Bi = (1-ki-ei)/m / (1 - (1-ki-ei)/m*∑Bj); 42 // Ci = ( (1-ki-ei)+(1-ki-ei)/m*∑Cj ) / (1 - (1-ki-ei)/m*∑Bj); 43 // 对于叶子节点: 44 // Ai = ki; 45 // Bi = 1 - ki - ei; 46 // Ci = 1 - ki - ei; 47 // wal = 1-ki-exi 48 if(flag)//叶子节点 49 { 50 t.a = p[x].ki; 51 t.b = p[x].wal; 52 t.c = p[x].wal; 53 } 54 else//非叶子节点 55 { 56 int m = ve[x].size(); 57 double f = 1 - p[x].wal / m*t1.b; 58 t.a =(p[x].ki + p[x].wal/m*t1.a) /f ; 59 t.b = p[x].wal/m/f ; 60 t.c = (p[x].wal + p[x].wal/m*t1.c) / f; 61 } 62 return t; 63 } 64 int main() 65 { 66 #ifdef debug 67 freopen("in.c","r",stdin); 68 #endif 69 int t; 70 scanf("%d",&t); 71 for(int d =1; d<=t ; ++d) 72 { 73 for(int i=1; i<=n; ++i) ve[i].clear(); 74 scanf("%d",&n); 75 for(int i=1; i<n; ++i) 76 { 77 int u,v; 78 scanf("%d%d",&u,&v); 79 ve[u].push_back(v); 80 ve[v].push_back(u); 81 } 82 for(int i=1; i<=n; ++i) 83 { 84 int k,e; 85 scanf("%d%d",&k,&e); 86 p[i].ki = (double)k/100.0; 87 p[i].wal = 1 - p[i].ki - (double)e/100.0; 88 } 89 memset(vis,0,sizeof(vis)); 90 para ans = dfs(1); 91 printf("Case %d: ",d); 92 if(fabs(ans.a-1) < eps) 93 printf("impossible "); 94 else 95 printf("%.6f ",ans.c/(1-ans.a)); 96 } 97 return 0; 98 }