[NOI 2005]聪聪和可可
Description
一只猫和一只老鼠在一张 \(n\) 个节点和 \(m\) 条边的无向图上,初始位置不同。对于每一时刻,猫会先走,它走的方向为靠近老鼠的方向;若多个节点可选,则选字典序最小的那个。同时若走出这步后没有抓到老鼠,则可按同样方式再走一步;接着老鼠会等概率的停在原地或者随机走向一个相邻的节点。问抓到老鼠的期望时间。
\(1\leq n,m\leq 1000\)
Solution
首先注意到这样一句话“若走出这步后没有抓到老鼠,则可按同样方式再走一步”,显然是能够保证猫一定能抓到老鼠。并且猫和老鼠两个所处位置的状态是具有层次性的。
容易发现老鼠的移动是没有规律的,即是随机的。而猫的动作是有规律的。
我们可以事先预处理出一个 \(pre_{u,v}\) 数组,表示猫在 \(u\) 处,老鼠在 \(v\) 处时,猫下一个选择要走的节点是哪一个,可以用 \(n\) 次 \(SPFA\) 预处理出来,由于边数和点数是同阶的,复杂度可以得到保障。
我们可以设出一个 \(dp\) 数组 \(f_{u,v}\) 表示猫在 \(u\) 处,老鼠在 \(v\) 处时期望走的时间为 \(f_{u,v}\) 。
首先显然当 \(u=v\) 时, \(f_{u,v}=0\) ;其次若 \(pre_{u,v}=v\) 即走出一步抓到老鼠或者 \(pre_{pre_{u,v},v}=v\) 即走出两步抓到老鼠, \(f_{u,v}=1\) 。
这时剩下的情况就是老鼠会移动。
由于猫会先走,猫移动之后老鼠再走;显然猫移动结束后停在的位置为 \(pre_{pre_{u,v},v}\) 。
设节点 \(v\) 以及和 \(v\) 相邻的节点的集合为 \(\mathbb{V}\) ,节点 \(v\) 的度数为 \(degree_v\) 。显然答案就是 \[f_{u,v}=\frac{\sum\limits_{x\in\mathbb{V}}f_{pre_{pre_{u,v},v},x}}{degree_v+1}+1\]
记忆化搜索实现。
Code
//It is made by Awson on 2018.2.24
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 1000;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(LL x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(LL x) {if (x < 0) putchar('-'); print(Abs(x)); }
int n, m, s, t, u, v;
struct tt {int to, next; }edge[(N<<1)+5];
int path[N+5], top, degree[N+5];
int pre[N+5][N+5]; double f[N+5][N+5];
queue<int>Q;
int vis[N+5], dist[N+5];
void add(int u, int v) {edge[++top].to = v, edge[top].next = path[u], path[u] = top, ++degree[u]; }
void get_pre(int x) {
memset(dist, 127/3, sizeof(dist)); dist[x] = 0, vis[x] = 1; Q.push(x);
while (!Q.empty()) {
int u = Q.front(); Q.pop(); vis[u] = 0;
for (int i = path[u]; i; i = edge[i].next)
if (dist[edge[i].to] > dist[u]+1) {
dist[edge[i].to] = dist[u]+1;
if (!vis[edge[i].to]) vis[edge[i].to] = 1, Q.push(edge[i].to);
if (u == x) pre[x][edge[i].to] = edge[i].to; else pre[x][edge[i].to] = pre[x][u];
}else if (dist[edge[i].to] == dist[u]+1 && pre[x][edge[i].to] > pre[x][u]) pre[x][edge[i].to] = pre[x][u];
}
}
double dp(int s, int t) {
if (s == t) return 0;
int nex = pre[pre[s][t]][t];
if (pre[s][t] == t || nex == t) return f[s][t] = 1;
if (f[s][t] != 0) return f[s][t];
double k = 1/(1.0*(degree[t]+1)); f[s][t] = 1+dp(nex, t)*k;
for (int i = path[t]; i; i = edge[i].next) f[s][t] += k*dp(nex, edge[i].to);
return f[s][t];
}
void work() {
read(n), read(m); read(s); read(t);
for (int i = 1; i <= m; i++) read(u), read(v), add(u, v), add(v, u);
for (int i = 1; i <= n; i++) get_pre(i);
printf("%.3lf\n", dp(s, t));
}
int main() {
work(); return 0;
}
[NOI 2005]聪聪和可可的更多相关文章
- 洛谷 P4206 [NOI2005]聪聪与可可 题解
题面 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行,每 ...
- [bzoj2152][聪聪和可可] (点分治+概率)
Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...
- BZOJ 1415 【NOI2005】 聪聪和可可
题目链接:聪聪和可可 一道水题--开始还看错题了,以为边带权--强行\(O(n^3)\)预处理-- 首先,我们显然可以预处理出一个数组\(p[u][v]\)表示可可在点\(u\),聪聪在点\(v\)的 ...
- 【bzoj1415】 Noi2005—聪聪和可可
http://www.lydsy.com/JudgeOnline/problem.php?id=1415 (题目链接) 题意 一张图,聪聪想吃可可.每单位时间聪聪可以先移动两次:可可后移动一次或停在原 ...
- bzoj1415[NOI2005]聪聪和可可
之前做的一些图上的期望步数的题大多用到高斯消元来求解(HNOI游走,SDOI走迷宫,etc),因此我一开始做这道题的时候想偏了- 这道题的性质:聪聪和可可之间的最短路长度严格递减.因为聪聪总可以多走一 ...
- 【BZOJ1415】 [Noi2005]聪聪和可可 概率与期望
其实题不难,不知提交了几次...不能代码MD...注意一些基本问题...SB概率题 #include <iostream> #include <cstdio> #include ...
- NOI2005 聪聪和可可
Sol 记忆化搜索. \(f[u][v]\) 表示聪聪在 \(u\) ,可可在 \(v\) ,聪聪抓到可可的期望. 预处理出 \(u\) 到 \(v\) 最短路径编号最小的点,记为 \(g[u][v] ...
- BZOJ 2152: 聪聪可可 树分治
2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
- bzoj 2152聪聪可可
2152: 聪聪可可 Time Limit: 3 Sec Memory Limit: 259 MB Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰 ...
- HYSBZ - 2152 聪聪和可可
Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...
随机推荐
- Struts2学习笔记五 拦截器
拦截器,在AOP中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作.拦截是AOP的一种实现策略. Struts2中,拦截器是动态拦截Action调用的对象.它提供了一种机制可以使 ...
- 使用idea新建jsp
使用idea解决新建jsp文件而找不到jsp文件模版的新建选项,这样每次创建一个新的jsp文件岂不是很耗时间? 解决办法: 就是要让idea知道你需要在这个目录下创建jsp文件 左上角,file中点击 ...
- 第一次作业:来自一个奋斗的IT学子
第一部分 结缘计算机 1.1你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 说起为何结缘了计算机,就得谈谈专业报考了,我觉得我的报考真是一个反面教科书了.由于高中以前每天只要想着 ...
- bug终结者 团队作业第三周
bug终结者 团队作业第三周 团队展示 队名 bug终结者 队员风采: 杨京典 20162302 风格:先构建框架,在一 一实现,在实现的过程中不断测试和修改. 擅长的技术:拆分问题,使用相对简单的思 ...
- verilog学习笔记(4)_有限状态机
有限状态机: 有限状态机是由寄存器组和组合逻辑构成的硬件时序电路: - 其状态(即由寄存器组的1和0的组合状态所构成的有限个状态)只能在同一时钟跳变沿的情况下才能从一个状态转向另一个状态: - 究竟转 ...
- [ZLXOI2015]殉国
2057. [ZLXOI2015]殉国 http://cogs.pro/cogs/problem/problem.php?pid=2057 ★☆ 输入文件:BlackHawk.in 输出文件: ...
- raid5 阵列硬盘离线数据恢复成功案例
数据恢复故障描述: 某研究院 DELL 磁盘阵列崩溃,内置15块1TB硬盘搭建的RAID5阵列.一开始有一块硬盘离线,在更换新硬盘进行同步的过程中,第二块磁盘指示灯报警,同步失败,阵列无法正常工作. ...
- c# windows service 实现监控其他程序是否被关闭,关闭则报警
namespace MonitorService { public partial class MonitorSv : ServiceBase { string AppName = "&qu ...
- java语法基础(总结)
1,关键字:其实就是某种语言赋予了特殊含义的单词. 保留字:其实就是还没有赋予特殊含义,但是准备日后要使用过的单词. 2,标示符:其实就是在程序中自定义的名词.比如类名,变量名,函数名.包含 0-9. ...
- SLF4J - 借助SLF4J, 统一适配所有日志实现为logback日志实现的实践
一.屏蔽各种日志实现,去掉各种日志实现的实现依赖 二.引入slf4j和各种日志实现的适配器 1.引入slf4j 2.引入各种日志实现的适配器(适配到slf4j) 3.引入logback 引入logba ...