Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 2012 Accepted Submission(s): 802
Special Judge
这道题我是看过题解才会做的。
真的是好题。
有时候,概率DP的转移方程写出来后,发现不能简单的递推得到,含有其他未知数,怎么办?
比如,y=f(x),要求出y,就要知道x,但是x的值又和y有关,这个时候可以列出几个方程,
消去未知数。
题解:
转自:http://blog.csdn.net/morgan_xww/article/details/6776947
注意:
1.若期望走的步数为无穷大,输出impossible
2.这道题卡精度,刚开始的时候精度设置为1e-8,wa了,改为1e-9才ac
我自己写的代码:
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 6 using namespace std; 7 8 const int maxn=1e4+10; 9 const double eps=1e-9; 10 11 double a[maxn]; 12 double b[maxn]; 13 double c[maxn]; 14 double k[maxn]; 15 double e[maxn]; 16 double res[maxn];//方便计算 17 18 struct Edge 19 { 20 int to,next; 21 }; 22 Edge edge[maxn<<1]; 23 int head[maxn],tot; 24 int sum[maxn]; //有多少条边和i相连 25 26 inline int sgn(double x) 27 { 28 if(fabs(x)<eps) 29 return 0; 30 return x>0?1:-1; 31 } 32 33 void init() 34 { 35 memset(head,-1,sizeof head); 36 tot=0; 37 memset(sum,0,sizeof sum); 38 } 39 40 void addedge(int u,int v) 41 { 42 edge[tot].to=v; 43 edge[tot].next=head[u]; 44 head[u]=tot++; 45 } 46 47 void cal_res(int N) 48 { 49 for(int i=1;i<=N;i++) 50 res[i]=(1.0-e[i]-k[i])/(double)sum[i]; 51 } 52 53 void dfs(int pre,int u) 54 { 55 if(u!=1&&sum[u]==1) 56 { 57 a[u]=k[u]; 58 b[u]=1.0-e[u]-k[u]; 59 c[u]=1.0-e[u]-k[u]; 60 return ; 61 } 62 double cnta=0.0; 63 double cntb=0.0; 64 double cntc=0.0; 65 for(int i=head[u];~i;i=edge[i].next) 66 { 67 int v=edge[i].to; 68 if(v==pre) 69 continue; 70 dfs(u,v); 71 cnta+=a[v]; 72 cntb+=b[v]; 73 cntc+=c[v]; 74 } 75 a[u]=(k[u]+res[u]*cnta)/(1.0-res[u]*cntb); 76 b[u]=(res[u])/(1.0-res[u]*cntb); 77 c[u]=(res[u]*cntc+1.0-e[u]-k[u])/(1.0-res[u]*cntb); 78 return ; 79 80 } 81 int main() 82 { 83 int test; 84 scanf("%d",&test); 85 int cas=1; 86 while(test--) 87 { 88 init(); 89 90 printf("Case %d: ",cas++); 91 int N; 92 scanf("%d",&N); 93 94 for(int i=1;i<N;i++) 95 { 96 int u,v; 97 scanf("%d%d",&u,&v); 98 addedge(u,v); 99 addedge(v,u); 100 sum[u]++; 101 sum[v]++; 102 } 103 for(int i=1;i<=N;i++) 104 { 105 scanf("%lf%lf",&k[i],&e[i]); 106 k[i]=k[i]/100.0; 107 e[i]=e[i]/100.0; 108 } 109 cal_res(N); 110 dfs(-1,1); 111 if(sgn(1.0-a[1]-0)<=0) 112 printf("impossible\n"); 113 else 114 { 115 double ans=c[1]/(1.0-a[1]); 116 printf("%.6f\n",ans); 117 } 118 } 119 return 0; 120 }