其他分享
首页 > 其他分享> > Vjudge 20220421练习10 D - Maze HDU - 4035

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