聪聪和可可

鸽了两天

\(dijkstra\)预处理出来两点之间的最短路径\(dis\)数组,读题发现,\(cat\)的走位很怪sb斩了,所以我们设一个\(next\)数组,\(next[i][j]\)表示\(cat\)在\(i\)位置,\(mouse\)在\(j\)位置时,\(cat\)下一步要去的位置,

设\(i\),\(j\)之间有一条边则

\[if\left(dis[i][k]-1==dis[k][j]\right) \\
next[i][k]=\min(next[i][k],j)
\]

考虑答案的转移,设\(u\)为\(cat\)当前所在的位置,\(v\)为\(mouse\)当前所在的位置,\(a\)为\(cat\)走一步所到的位置,\(b\)为\(cat\)走两步所到的位置,\(to\)为\(mouse\)可到达的位置最后记得算上一开始的v,\(du\)数组为该点的出度记得加上自己,则有以下三种情况

\[if\left(u==v\right)\;\;return 0; \\
if(a==v||b==v)\;\;return 1; \\
else\;\;dp[u][v]+=\frac{dfs\left(b,to\right)}{\left(du[v]+1\right)}
\]

最后记得算上\(mouse\)一开始所在的位置\(v\)

\[dp[u][v]+=\frac{dfs\left(b,v\right)}{\left(du[v]+1\right)}
\]

以上求答案的过程可用\(dfs\)解决

Code:

#include<cstdio>
#include<queue>
#define MAX 1001
#define re register
#define INF 114514
namespace OMA
{
int n,e,c,m;
int dis[MAX][MAX];
int cnt=1,head[MAX];
int du[MAX],next[MAX][MAX];
double dp[MAX][MAX];
bool pre[MAX],vis[MAX][MAX];
struct node
{
int next;
int to;
}edge[MAX<<1];
typedef std::pair<int,int>oma;
std::priority_queue<oma,std::vector<oma>,std::greater<oma> >q;
inline int read()
{
int s=0,w=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ s=s*10+ch-'0'; ch=getchar(); }
return s*w;
}
inline void add(int u,int v)
{
edge[++cnt].next = head[u];
edge[cnt].to = v;
head[u] = cnt;
}
inline int min(int a,int b)
{ return a<b?a:b; }
void in()
{
n=read(),e=read(),c=read(),m=read();
for(re int i=1; i<=e; i++)
{
int u=read(),v=read();
add(u,v),add(v,u);
du[u]++,du[v]++;
}
for(re int i=1; i<=n; i++)
{
for(re int j=1; j<=n; j++)
{ next[i][j] = INF; }
}
}
inline void dijkstra(int u)
{
for(re int i=1; i<=n; i++)
{ dis[u][i] = INF ,pre[i] = false; }
while(!q.empty())
{ q.pop(); }
dis[u][u] = 0;
q.push(std::make_pair(0,u));
while(!q.empty())
{
int k = q.top().second;
q.pop();
if(pre[k])
{ continue; }
pre[k] = true;
for(re int i=head[k]; i; i=edge[i].next)
{
int to = edge[i].to;
if(!pre[to]&&(dis[u][to]>dis[u][k]+1))
{
dis[u][to] = dis[u][k]+1;
q.push(std::make_pair(dis[u][to],to));
}
}
}
}
inline double dfs(int cat,int mouse)
{
if(vis[cat][mouse])
{ return dp[cat][mouse]; }
if(cat==mouse)
{ return 0; }
int a,b;
a = next[cat][mouse];
b = next[a][mouse];
if(a==mouse||b==mouse)
{ return 1; }
dp[cat][mouse] = 1;
for(re int i=head[mouse]; i; i=edge[i].next)
{
int to = edge[i].to;
dp[cat][mouse] += dfs(b,to)/(du[mouse]+1);
}
dp[cat][mouse] += dfs(b,mouse)/(du[mouse]+1);
vis[cat][mouse] = 1;
return dp[cat][mouse];
}
signed main()
{
in();
for(re int i=1; i<=n; i++)
{ dijkstra(i); }
for(re int i=1; i<=n; i++)
{
for(re int j=head[i]; j; j=edge[j].next)
{
int to = edge[j].to;
for(re int k=1; k<=n; k++)
{
if(dis[i][k]-1==dis[k][to])
{ next[i][k] = min(next[i][k],to); }
}
}
}
printf("%.3lf\n",dfs(c,m));
return 0;
}
}
signed main()
{ return OMA::main(); }

luogu P4206 聪聪和可可的更多相关文章

  1. luogu P4206 [NOI2005]聪聪与可可 期望dp 记忆化搜索

    LINK:聪聪与可可 这道题的核心是 想到如何统计答案. 如果设f[i][j]表示第i个时刻... 可以发现还需要统计位置信息 以及上一次到底被抓到没有的东西 不太好做. 两者的位置都在变化 所以需要 ...

  2. P4206[NOI2005]聪聪与可可

    链接P4206 [NOI2005]聪聪与可可 类似于开车旅行,如果老鼠确定了那么猫的路线是确定的. 预处理\(g_{i,j}\)表示老鼠在\(i\)号点,猫的下一步方向,\(Bfs\)就行了 设\(f ...

  3. Luogu 4206 [NOI2005]聪聪与可可

    BZOJ 1415 简单期望 + 记忆化搜索. 发现聪聪每一步走向的地方是在可可的所在位置确定时是确定的,设$nxt_{x, y}$表示聪聪在$x$,可可在$y$时聪聪下一步会走到哪里,我们先预处理出 ...

  4. [luogu 2634]聪聪可可

    题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已 ...

  5. luogu P2634 [国家集训队]聪聪可可 点分治

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  6. 洛谷 P4206 [NOI2005]聪聪与可可 题解

    题面 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行,每 ...

  7. 【P2634】聪聪可可——点分治

    (题面来自Luogu) 题目描述 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)--遇到这种问题,一般情况下石头 ...

  8. [bzoj2152][聪聪和可可] (点分治+概率)

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  9. BZOJ 1415 【NOI2005】 聪聪和可可

    题目链接:聪聪和可可 一道水题--开始还看错题了,以为边带权--强行\(O(n^3)\)预处理-- 首先,我们显然可以预处理出一个数组\(p[u][v]\)表示可可在点\(u\),聪聪在点\(v\)的 ...

随机推荐

  1. 南京大学计算机基础 ELF和可执行文件格式

    1.可重定位目标文件格式 主要是由ELF头,一些节比如.text节,.rodata节,.data节,.bss节等,前面是只读的,后面是可读可写的,加上一个节头表 1.1 ELF头里面主要包含了16字节 ...

  2. Parrot os 安装vmtools

    1.更新源(这步个人觉得官方源还可以,没网上说的那么慢) vim /etc/apt/sources.list.d/parrot.list linux命令 ,按i进入修改模式,修改结束,之后先按esc, ...

  3. CSS 奇思妙想 | 巧妙的实现带圆角的三角形

    之前在这篇文章中 -- <老生常谈之 CSS 实现三角形>,介绍了 6 种使用 CSS 实现三角形的方式. 但是其中漏掉了一个非常重要的场景,如何使用纯 CSS 实现带圆角的三角形呢?,像 ...

  4. 【网络IO系列】IO的五种模型,BIO、NIO、AIO、IO多路复用、 信号驱动IO

    前言 在上一篇文章中,我们了解了操作系统中内核程序和用户程序之间的区别和联系,还提到了内核空间和用户空间,当我们需要读取一条数据的时候,首先需要发请求告诉内核,我需要什么数据,等内核准备好数据之后 , ...

  5. ArrayList 从源码角度剖析底层原理

    本篇文章已放到 Github github.com/sh-blog 仓库中,里面对我写的所有文章都做了分类,更加方便阅读.同时也会发布一些职位信息,持续更新中,欢迎 Star 对于 ArrayList ...

  6. gpasswd简单记录

    gpasswd [option] GROUP 一切都是为了权限 gpasswd常用参数: -a, --add  USER 将user用户加入到组中 -d, --delete  USER 将user用户 ...

  7. JProfiler监控java应用使用情况,故障情况分析

    1.软件部署(java环境已提前准备) 服务器:centos7.4 https://download-gcdn.ej-technologies.com/jprofiler/jprofiler_linu ...

  8. Map集合笔记

    一.Map集合的特点 Map集合是一个双列集合 Map中的元素,key和value的数据类型可以相同,也可以不同. Map中的元素,key是允许重复的,value是可以重复的 Map中的元素,key和 ...

  9. JDK的环境变量配置(详细步骤)

    JDK环境变量配置的步骤(Windows10) 一.下载并安装JDK 选择一个JDK版本下载并安装到电脑上. 二.环境变量的配置 1.安装完成JDK后的配置环境变量: 首先鼠标右击"计算机& ...

  10. 微信小程序云开发-云存储的应用-识别驾驶证

    一.准备工作 1.创建云函数identify 2.云函数identify中index.js代码 1 // 云函数入口文件 2 const cloud = require('wx-server-sdk' ...