解题:SHOI 2014 概率充电器
Posted ydnhaha
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解题:SHOI 2014 概率充电器相关的知识,希望对你有一定的参考价值。
显然就是在求概率,因为期望乘的全是1.。。。然后就推推推啊
设$fgg[i]$表示这个点父亲没给他充上电的概率,$sgg[i]$表示这个点子树(和它自己没给他充上电的概率),然后这个点没充上电的概率就是$fgg[i]*sgg[i]$
我们发现我们在树上转移的话$fgg$反过来依赖儿子,也就是依赖于$sgg$,那我们先把$sgg$求出来
$sgg[i]=$
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=500005,M=1e6+60; 6 int p[N],noww[M],goal[M],n,t1,t2,cnt; 7 double val[M],pos[N],sgg[N],fgg[N],mem[N],t3,ans; 8 void Link(int f,int t,double v) 9 { 10 noww[++cnt]=p[f],p[f]=cnt; 11 goal[cnt]=t,val[cnt]=v; 12 } 13 void Gettre(int nde,int fth) 14 { 15 sgg[nde]=1-pos[nde]; 16 for(int i=p[nde];i;i=noww[i]) 17 if(goal[i]!=fth) 18 { 19 int g=goal[i]; Gettre(g,nde); 20 mem[g]=sgg[g]+(1-sgg[g])*(1-val[i]); 21 sgg[nde]*=mem[g]; 22 } 23 } 24 void Getans(int nde,int fth) 25 { 26 ans-=sgg[nde]*fgg[nde]; 27 for(int i=p[nde];i;i=noww[i]) 28 if(goal[i]!=fth) 29 { 30 int g=goal[i]; 31 double fag=sgg[nde]*fgg[nde]/mem[g]; 32 fgg[g]=fag+(1-fag)*(1-val[i]),Getans(g,nde); 33 } 34 } 35 int main() 36 { 37 scanf("%d",&n),ans=n; 38 for(int i=1;i<n;i++) 39 { 40 scanf("%d%d%lf",&t1,&t2,&t3); 41 Link(t1,t2,t3/100),Link(t2,t1,t3/100); 42 } 43 for(int i=1;i<=n;i++) 44 scanf("%lf",&pos[i]),pos[i]/=100; 45 Gettre(1,0),fgg[1]=1,Getans(1,0),printf("%.6f",ans); 46 return 0; 47 }
以上是关于解题:SHOI 2014 概率充电器的主要内容,如果未能解决你的问题,请参考以下文章