Vjudge 20220421练习10 D - Maze HDU - 4035
作者:互联网
written on 2022-04-22
题目描述:
有n个房间,由n-1条隧道连通起来,从结点1出发,开始走,在每个结点i都有3种可能:
1.被杀死,回到结点1处(概率为ki)
2.找到出口,走出迷宫 (概率为ei)
3.和该点相连有m条边,随机走一条 求:走出迷宫所要走的边数的期望值。
PS:题目中的边数指的是共走过的边数,那么被杀死回到原点以及直接逃出就不耗步数
期望题,用到数学推导,想法很妙,思路来源很迷,,大有启发,分析过程太长,这里直接贴题解好了
#include<bits/stdc++.h>
#define N 10005
using namespace std;
int n;
int tot,ver[N<<1],nxt[N<<1],head[N];
void add_E(int x,int y){ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
double p[N],q[N],c[N],A[N],B[N],C[N];
const double eps=1e-9;
bool check(double x){return fabs(x)<=eps;}
void dfs(int x,int fa)
{
double suma=0,sumb=0,sumc=0;
int m=0;
bool flag=1;
for(int i=head[x];i;i=nxt[i])
{
int y=ver[i];
m++;
if(y==fa) continue;
flag=0;
dfs(y,x);
suma+=A[y],sumb+=B[y],sumc+=C[y];
}
if(flag)
{
A[x]=p[x],B[x]=c[x],C[x]=c[x];
return ;
}
double t=1-c[x]*sumb/m;
A[x]=(p[x]+c[x]*suma/m)/t,B[x]=(c[x]/m)/t,C[x]=(c[x]+c[x]*sumc/m)/t;
}
int main()
{
int T;
scanf("%d",&T);
for(int rnd=1;rnd<=T;rnd++)
{
tot=0,memset(head,0,sizeof(head));
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add_E(x,y),add_E(y,x);
}
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&p[i],&q[i]);
p[i]/=100,q[i]/=100;
c[i]=1-p[i]-q[i];
}
dfs(1,0);
printf("Case %d: ",rnd);
if(check(A[1]-1)) puts("impossible");
else printf("%.6lf\n",C[1]/(1-A[1]));
}
}
/*
1.题目中的边数指的是共走过的边数,那么被杀死回到原点以及直接逃出就不耗步数
2.树形dp维护的值只用维护A,B,C,均与父节点无关
3.E[1]与fa本身就无关,知道A1 B1 C1后就能推出E[1]了
*/
标签:10,HDU,题目,int,题解,迷宫,结点,Vjudge,边数 来源: https://www.cnblogs.com/Freshair-qprt/p/16537690.html