您的位置:首页 > 其它

HDU 4035 Maze(树形概率DP)

2013-05-04 22:36 435 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4035

题意:一棵树,从结点1出发,在每个结点 i 都有3种可能:(1)回到结点1 , 概率 Ki;(2)结束,概率 Ei;(3)随机走一条边。(Ki+Ei+随机走=1) 求到结束需要走的边数的期望。

思路:设Q[i]表示从i到结束的期望,设Q[i]=A[i]*Q[1]+B[i]*Q[fa[i]]+C[i]。

对于叶子节点,Q[i]=K[i]*Q[1]+E[i]*0+(1-K[i]-E[i])*(Q[fa[i]]+1),

对于叶子节点那么我们可得到:A[i]=K[i],B[i]=1-K[i]-E[i],C[i]=1-K[i]-E[i]。

对于非叶子节点,设与其相连的点有m个,则到每个点的概率都是temp=(1-K[i]-E[i])/m,Q[i]=K[i]*Q[1]+E[i]*0+temp*(Q[fa[i]]+Q[son[1]]+Q[son[2]+……Q[son[m-1]]]+1)。

计算出其子节点带入得到:令X=1-temp*sum(B[son[i]]),

A[i]=(K[i]+temp*sum(A[son[i]]))/X

B[i]=(1-K[i]-E[i])/m/X

C[i]=(1-K[i]-E[i]+temp*sum(C[son[i]]))/X

那么无解有两种情况:(1)中间计算过程出现X=0;(2)Q[1]=A[1]*Q[1]+B[1]+C[1],A[1]=1。

double A
,B
,C
,K
,E
;
vector<int> g
;
int n;

int flag;

void DFS(int u,int pre)
{
A[u]=K[u];
B[u]=(1-K[u]-E[u])/SZ(g[u]);
C[u]=1-K[u]-E[u];
int i,v;
double temp=(1-K[u]-E[u])/SZ(g[u]),x=1;
FOR0(i,SZ(g[u]))
{
v=g[u][i];
if(v==pre) continue;
DFS(v,u);
A[u]+=temp*A[v];
x-=temp*B[v];
C[u]+=temp*C[v];
}
if(fabs(x)<EPS) flag=1;
else A[u]/=x,B[u]/=x,C[u]/=x;
}

int main()
{
int num=0;
rush()
{
RD(n);
int i,u,v;
FOR1(i,n) g[i].clear();
FOR1(i,n-1)
{
RD(u,v);
g[u].pb(v);
g[v].pb(u);
}
FOR1(i,n) RD(K[i],E[i]),K[i]/=100,E[i]/=100;
flag=0;
DFS(1,-1);
printf("Case %d: ",++num);
if(fabs(A[1]-1)<EPS||flag) puts("impossible");
else PR(C[1]/(1-A[1]));
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: