首页 > 其他分享 >【洛谷】P4206 [NOI2005] 聪聪与可可(概率+记忆化搜索)

【洛谷】P4206 [NOI2005] 聪聪与可可(概率+记忆化搜索)

时间:2023-03-13 15:57:36浏览次数:46  
标签:洛谷 idx int fxt zjzj P4206 NOI2005 include 节点

原题链接

题意

给定一张 \(n\) 个节点 \(m\) 条边的无向图,初始时,A_zjzj 在 \(S\),fxt 在 \(T\),现在 A_zjzj 要前去抓住 fxt。

  • A_zjzj 只会往使得两人的最短距离减 \(1\) 的点前进,如果有多个这样的点,他会走编号最小的一个节点。

  • 如果 A_zjzj 在走完这一步后并没有抓住 fxt,那么他在这一秒内还会重复执行上述动作。

  • 当 A_zjzj 走完以后,fxt 会等概率走向相邻的节点或停留在原地不动。

上述操作均在一秒钟内进行,求 A_zjzj 抓住 fxt 的期望时间。

\(1 \leq n,m \leq 1000\)。

思路

由于边权都为 \(1\),可以对每个节点 bfs 一遍预处理出任意两点的最短距离,时间复杂度为 \(O(n(n+m))\)。

设 \(p_{u,v}\) 为 A_zjzj 在 \(u\) 节点,fxt 在 \(v\) 节点时 A_zjzj 接下来会走到的节点。这一部分也可以预处理得出。

设 \(p_{P_{u,v},v}=x\),即 A_zjzj 走两步以后会到达的节点。设 \(f_{u,v}\) 为 A_zjzj 在 \(u\) 节点,fxt 在 \(v\) 节点时的答案。令 \(d_u\) 为与 \(u\) 相邻的节点个数,那么可以得出转移方程:

\[f_{u,v}=\dfrac{f_{x,v}+\sum_{k \in son_v} f_{x,k}}{d_u+1} \]

由于 A_zjzj 只会往特点的节点走,所以这里不会出现成环的情况,于是只需要记忆化搜索即可。

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1010,M=2023;
int q[N],h[N],idx,n,m,p[N][N],d[N][N];double f[N][N];
struct edge{int v,nex;}e[M];
void add(int u,int v){e[++idx]=edge{v,h[u]};h[u]=idx;}
void bfs(int S)
{
	int hh=0,tt=-1;q[++tt]=S;memset(d[S],0x3f,sizeof(d[S]));d[S][S]=0;
	while(hh<=tt)
	{
		int u=q[hh++];
		for(int i=h[u];i;i=e[i].nex)
		{
			int v=e[i].v;if(d[S][v]<=d[S][u]+1) continue;
			d[S][v]=d[S][u]+1;q[++tt]=v;
		}
	}
}
double dp(int u,int T)
{
	if(u==T) return f[u][T]=0.0;
	if(p[u][T]==T||p[p[u][T]][T]==T) return f[u][T]=1.0;
	if(f[u][T]!=0.0) return f[u][T];f[u][T]=dp(p[p[u][T]][T],T);int cnt=1;
	for(int i=h[T];i;i=e[i].nex) 
	{
		int v=e[i].v;f[u][T]+=dp(p[p[u][T]][T],v);cnt++;
	}
	f[u][T]/=1.0*cnt;return f[u][T]+=1.0;
}
int main()
{
	scanf("%d%d",&n,&m);int S,T;scanf("%d%d",&S,&T); 
	for(int u,v,i=1;i<=m;i++) scanf("%d%d",&u,&v),add(u,v),add(v,u);
	for(int i=1;i<=n;i++) bfs(i);memset(p,0x3f,sizeof(p));
	for(int u=1;u<=n;u++)
		for(int i=h[u];i;i=e[i].nex)
			for(int j=1;j<=n;j++)
				if(d[u][j]==d[e[i].v][j]+1) p[u][j]=min(p[u][j],e[i].v);
	printf("%.3lf\n",dp(S,T));
	return 0;
}

标签:洛谷,idx,int,fxt,zjzj,P4206,NOI2005,include,节点
From: https://www.cnblogs.com/ListenSnow/p/17211698.html

相关文章

  • 洛谷 P1015 回文数
    P1015回文数https://www.luogu.com.cn/problem/P1015原题很明显的高精度,(1999年竟然就考主要有:高精度加法(含进位)、高精度判断回文数以及可以把字符串转成数字数组......
  • 洛谷-2822
    洛谷-2652key思路有个modk的想法很好,然后就是对于一遍一遍的询问进行前缀和优化,但有个问题就是算出来的s矩阵最开始是个下三角矩阵,但是根据前缀和公式来看,s[i][j]上方......
  • 【洛谷】P3365 改造二叉树(LIS)
    原题链接题意给定一颗二叉树,每次操作可以修改一个点的权值为任意整数,求将原树变为二叉搜索树的最小操作次数。注意:本题中的二叉搜索树定义为:每个左边儿子的权值都严格小......
  • 洛谷P1213 [USACO1.4][IOI1994]时钟 The Clocks
    这是一个暴力枚举题有两种解决方法,第一种用九重for循环(有点麻烦,尽量别用),第二种简化版(虽然行数少了,但难理解),先来看看 题目!!!题目描述考虑将如此安排在一个 3*3 行......
  • 进制转换 洛谷P1017
    题目传送门题目描述我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所处位置为指数,以 1010 为底数的幂之和的形式。例如 123123 可表......
  • 洛谷P1036
    P1036[NOIP2002普及组]选数典型的dfs,建议书写递归代码时层次应与形参列表中自己所标志的层次相对应,否则很容易混乱importjava.util.Scanner;publicclassP1036......
  • 洛谷P1030
    P1030[NOIP2001普及组]求先序排列思路:由后序遍历序列求出根由中序遍历序列求出左右子树递归上述12直到中序/后续遍历序列为空publicclassP1030{//已......
  • 洛谷P1149 [NOIP2008 提高组] 火柴棒等式
    这道题就是一个经典的暴力枚举题意是输出一共有的火柴根数,输出这些火柴棒用完可以有多少拼法下面,我们来数一数拼成十个数和两个符号(’+‘&&’=‘)各用几根火柴棒0要用......
  • 洛谷P1149 [NOIP2008 提高组] 火柴棒等式
    这道题其实很简单只是个暴力枚举!!!题目大致意思是说给你一堆火柴棒,两个符号(‘+’&&‘-’)。第一个数字‘0’用了6根火柴棒,‘1’用了2根火柴棒,依此类推......这样,我们就能......
  • 洛谷 P4048更新题面
    [JSOI2010]冷冻波题目描述WJJ喜欢“魔兽争霸”这个游戏。在游戏中,巫妖是一种强大的英雄,它的技能FrozenNova每次可以杀死一个小精灵。我们认为,巫妖和小精灵都可以看成......