标签:des style blog color io os ar java for
3 3 1 2 1 3 0 0 100 0 0 100 3 1 2 2 3 0 0 100 0 0 100 6 1 2 2 3 1 4 4 5 4 6 0 0 20 30 40 30 50 50 70 10 20 60
Case 1: 2.000000 Case 2: impossible Case 3: 2.895522
dp求期望的题。
题意:
有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树,
从结点1出发,开始走,在每个结点i都有3种可能:
1.被杀死,回到结点1处(概率为ki)
2.找到出口,走出迷宫 (概率为ei)
3.和该点相连有m条边,随机走一条
求:走出迷宫所要走的边数的期望值。
设 E[i]表示在结点i处,要走出迷宫所要走的边数的期望。E[1]即为所求。
叶子结点:
E[i] = ki*E[1] + ei*0 + (1-ki-ei)*(E[father[i]] + 1);
= ki*E[1] + (1-ki-ei)*E[father[i]] + (1-ki-ei);
非叶子结点:(m为与结点相连的边数)
E[i] = ki*E[1] + ei*0 + (1-ki-ei)/m*( E[father[i]]+1 + ∑( E[child[i]]+1 ) );
= ki*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei)/m*∑(E[child[i]]) + (1-ki-ei);
设对每个结点:E[i] = Ai*E[1] + Bi*E[father[i]] + Ci;
对于非叶子结点i,设j为i的孩子结点,则
∑(E[child[i]]) = ∑E[j]
= ∑(Aj*E[1] + Bj*E[father[j]] + Cj)
= ∑(Aj*E[1] + Bj*E[i] + Cj)
带入上面的式子得
(1 - (1-ki-ei)/m*∑Bj)*E[i] = (ki+(1-ki-ei)/m*∑Aj)*E[1] + (1-ki-ei)/m*E[father[i]] + (1-ki-ei) + (1-ki-ei)/m*∑Cj;
由此可得
Ai = (ki+(1-ki-ei)/m*∑Aj) / (1 - (1-ki-ei)/m*∑Bj);
Bi = (1-ki-ei)/m / (1 - (1-ki-ei)/m*∑Bj);
Ci = ( (1-ki-ei)+(1-ki-ei)/m*∑Cj ) / (1 - (1-ki-ei)/m*∑Bj);
对于叶子结点
Ai = ki;
Bi = 1 - ki - ei;
Ci = 1 - ki - ei;
从叶子结点开始,直到算出 A1,B1,C1;
E[1] = A1*E[1] + B1*0 + C1; //因为根节点无父节点
所以
E[1] = C1 / (1 - A1);
若 A1趋近于1则无解...
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
#define N 10005
#define LL __int64
vector<int>g[N];
const double eps=1e-10;
double a[N],b[N],c[N],e[N],k[N];
bool dfs(int t,int pre)
{
int i,m=g[t].size();
a[t]=k[t];
b[t]=(1-k[t]-e[t])/m;
c[t]=1-k[t]-e[t];
double tmp=0;
for(i=0;i<m;i++)
{
int v=g[t][i];
if(v==pre)
continue;
if(!dfs(v,t))
return false;
a[t]+=a[v]*(1-k[t]-e[t])/m;
c[t]+=c[v]*(1-k[t]-e[t])/m;
tmp+=b[v]*(1-k[t]-e[t])/m;
}
if(fabs(1-tmp)<eps)
return false;
a[t]/=(1-tmp);
b[t]/=(1-tmp);
c[t]/=(1-tmp);
return true;
}
int main()
{
int T,i,n,u,v,cnt=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<=n;i++)
g[i].clear();
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&k[i],&e[i]);
k[i]/=100;
e[i]/=100;
}
printf("Case %d: ",cnt++);
if(dfs(1,-1)&&fabs(1-a[1])>eps)
{
double ans=c[1]/(1-a[1]);
printf("%.8f\n",ans);
}
else
printf("impossible\n");
}
return 0;
}
标签:des style blog color io os ar java for
原文地址:http://blog.csdn.net/u011721440/article/details/40263867