标签:10 HDU 题目 int 题解 迷宫 结点 Vjudge 边数
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
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。