[题解]HDU4035 Maze
Posted scl123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[题解]HDU4035 Maze相关的知识,希望对你有一定的参考价值。
题目描述
一棵(n)个节点的树,从1号结点开始游戏,在每一个点(x):
- 有(a[x]/100)的可能掉进陷阱死翘翘回到1重新开始
- 有(b[x]/100)的可能找到出口并结束游戏
- 剩下的可能中,你等概率随机选一条和它相连的边(可以是父亲)走过去
问期望多少步结束游戏
(1leq T leq 30,1leq n leq 10000)
分析
设(dp[x])表示位于(x)节点时,期望走几步才能结束游戏
那么(dp[x]=0.01a[x]*dp[1]+0.01b[x]*0+0.01(1-a[x]-b[x])*(frac{1}{cnt}(sum dp[son]+dp[1]+1)))
看了一下数据范围发现并不能承受高斯消元的时间复杂度
我们发现,每一个点的(dp)值之和父亲、1号点还有儿子有关,那么叶子节点的(dp)值可以用父亲和1号点表示,这样往上代,合并同类项之后可以发现,每一个点的值都可以表示为:
(dp[x]=...*dp[1]+...*dp[fa[x]]+...)(常数项)
所以只需要维护一下每一项的系数就可以(O(n))求解了,记得特判Impossible
代码
void SEARCH(int x,int pa){
f[x][0]=f[x][1]=f[x][2]=0;
int cnt=0;
for(int r=lst[x];r;r=nxt[r]){
cnt++;
if(edge[r]==pa)continue;
SEARCH(edge[r],x);
}
DB lef=(100-a[x]-b[x])*0.01;
DB hlp=0;
for(int r=lst[x];r;r=nxt[r]){
if(edge[r]==pa)continue;
int pos=edge[r];
f[x][0]+=f[pos][0];
f[x][2]+=f[pos][2];
hlp+=f[pos][1];
}
f[x][0]=(lef*f[x][0])/(1.0*cnt)+a[x]*0.01;
f[x][2]=(lef*f[x][2])/(1.0*cnt)+lef;
if(x==1)f[x][1]=0;else f[x][1]=lef/(1.0*cnt);
hlp=hlp*lef/(1.0*cnt);
hlp=1.0-hlp;
if(x==1)hlp-=f[x][0];
if(hlp<=0)f[x][0]=f[x][1]=f[x][2]=0;
else rep(i,0,2)f[x][i]/=hlp;
}
以上是关于[题解]HDU4035 Maze的主要内容,如果未能解决你的问题,请参考以下文章