\(\\\)

\(Description\)


一张\(N\)个点,\(M\)条边的有向图中,猫在\(A\)点,鼠在\(B\)点,每一秒两者按照以下规则移动:

  • 猫先走去往老鼠所在地的最短路,可以走一步或两步,多条路径的话走点编号最小的。
  • 鼠等概率移动到直接连通的一个点或不动(概率为\(\frac{1}{deg_v+1}\))。

当任意时刻猫到达鼠所在地时鼠被吃掉,求鼠被吃掉的期望时间。

  • \(N,M\in [0,10^3]\)

\(\\\)

\(Solution\)


BZOJ200题达成纪念

  • 注意到图非常稀疏,可以\(SPFA\)预处理出,对于任意点对\((x,y)\),\(x\)按规则走向\(y\)的第一步去往的点\(next[x][y]\)。

  • 具体操作是现对每个点跑一遍\(SPFA\),设\(dis[u][v]\)表示从\(u\)到\(v\)的最短路长度,则所找的点的编号\(next[x][y]=min\{v|dis[v][y]+1=dis[x][y]\}\)。那么对于每一个要处理的猫和鼠的地点\((A,B)\),猫下一步到达的点就是\(next[next[A][B]][B]\)。

  • 注意到猫每一秒都会向靠近鼠的方向移动两步,而鼠每一秒会向不确定的方向移动一步,所以鼠是一定会被吃掉的,不妨暴力\(dfs\)下去找到猫捉到鼠的时间。而搜索状态量过多,所以需要记忆化。设\(f[i][j]\)表示猫在\(i\)号节点,鼠在\(j\)号节点时时间的期望,那么初始化就是\(f[i][i]=0,f[i][j]=1\big|dis[i][j]\le 2,i\not=j\)。

  • 然后记搜就可以了,转移方程很好理解,就是猫走向该走的地方,鼠下一步枚举,没搜过就搜一下:

    \[f[i][j]=\frac{\sum_{dis[j][v]=1}f\big[next[next[i][j]][j]\big]\big[v\big]\ +\ f\big[next[next[i][j]][j]\big]\big[j\big]}{deg[j]+1}+1
    \]

\(\\\)

\(Code\)


#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1010
#define R register
#define gc getchar
#define inf 2000000000
using namespace std; inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
} bool vis[N];
double f[N][N];
int n,m,s,t,tot,hd[N],d[N][N],deg[N],nxt[N][N]; struct edge{int to,nxt;} e[N<<1];
inline void add(int u,int v){
e[++tot].to=v; e[tot].nxt=hd[u]; hd[u]=tot;
} queue<int> q;
inline void bfs(int x){
q.push(x); d[x][x]=0;
while(!q.empty()){
int u=q.front(); q.pop(); vis[u]=0;
for(R int i=hd[u],v;i;i=e[i].nxt)
if(d[x][v=e[i].to]>d[x][u]+1){
d[x][v=e[i].to]=d[x][u]+1; if(!vis[v]) vis[v]=1,q.push(v);
}
}
} inline void dfs(int u,int v){
double res=0.0;
int nu=nxt[nxt[u][v]][v];
for(R int i=hd[v],nv;i;i=e[i].nxt){
if(f[nu][nv=e[i].to]<-10) dfs(nu,nv);
res+=f[nu][nv];
}
if(f[nu][v]<-10) dfs(nu,v);
f[u][v]=(res+f[nu][v])/(deg[v]+1)+1;
} int main(){
n=rd(); m=rd(); s=rd(); t=rd();
for(R int i=1,u,v;i<=m;++i){
u=rd(); v=rd(); add(u,v); add(v,u);
}
for(R int i=1;i<=n;++i)
for(R int j=1;j<=n;++j) d[i][j]=nxt[i][j]=inf,f[i][j]=-(double)inf;
for(R int i=1;i<=n;++i) bfs(i);
for(R int i=1;i<=n;++i)
for(R int j=1;j<=n;++j)
if(d[i][j]<inf) for(R int k=hd[i],v;k;k=e[k].nxt)
if(d[v=e[k].to][j]+1==d[i][j]) nxt[i][j]=min(nxt[i][j],v);
for(R int i=1;i<=n;++i){
for(R int j=1;j<=n;++j) if(d[i][j]<=2) f[i][j]=1;
f[i][i]=0;
for(R int j=hd[i];j;j=e[j].nxt) ++deg[i];
}
if(f[s][t]<-1) dfs(s,t);
printf("%.3lf\n",f[s][t]);
return 0;
}

[ NOI 2005 ] 聪聪与可可的更多相关文章

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

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

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

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

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

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

  4. 【bzoj1415】 Noi2005—聪聪和可可

    http://www.lydsy.com/JudgeOnline/problem.php?id=1415 (题目链接) 题意 一张图,聪聪想吃可可.每单位时间聪聪可以先移动两次:可可后移动一次或停在原 ...

  5. bzoj1415[NOI2005]聪聪和可可

    之前做的一些图上的期望步数的题大多用到高斯消元来求解(HNOI游走,SDOI走迷宫,etc),因此我一开始做这道题的时候想偏了- 这道题的性质:聪聪和可可之间的最短路长度严格递减.因为聪聪总可以多走一 ...

  6. 【BZOJ1415】 [Noi2005]聪聪和可可 概率与期望

    其实题不难,不知提交了几次...不能代码MD...注意一些基本问题...SB概率题 #include <iostream> #include <cstdio> #include ...

  7. NOI2005 聪聪和可可

    Sol 记忆化搜索. \(f[u][v]\) 表示聪聪在 \(u\) ,可可在 \(v\) ,聪聪抓到可可的期望. 预处理出 \(u\) 到 \(v\) 最短路径编号最小的点,记为 \(g[u][v] ...

  8. BZOJ 2152: 聪聪可可 树分治

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

  9. bzoj 2152聪聪可可

    2152: 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MB Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰 ...

  10. HYSBZ - 2152 聪聪和可可

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

随机推荐

  1. codeforces 371c

    #include<stdio.h> int main() { char s[200]; __int64  r,nb,ns,nc,pb,ps,pc,i,sum,tob,tos,toc; wh ...

  2. [K/3Cloud]屏蔽页签的关闭按钮

    如图,屏蔽企业门户的X关闭按钮. this.View.GetControl<TabControl>("FMainTab").SetItemCloseable(1, fa ...

  3. Calculate S(n)

    Problem Description Calculate S(n). S(n)=13+23 +33 +......+n3 .   Input Each line will contain one i ...

  4. JAVA内存模型与线程以及volatile理解

    Java内存模型是围绕在并发过程中如何处理原子性.可见性.有序性来建立的. 一.主内存与工作内存 Java内存模型主要目标是在虚拟机中将变量存储到内存和从内存中取出变量.这里的变量包括:实例字段.静态 ...

  5. HDU——1133 Buy the Ticket

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  6. ZOJ——3609 Modular Inverse

    Modular Inverse Time Limit: 2 Seconds      Memory Limit: 65536 KB The modular modular multiplicative ...

  7. postgresql备份和恢复

    备份: pg_dump -d m3vg -h localhost -p 5432 -U delta -W -f 1024.dump -F tar 恢复: pg_restore -h localhost ...

  8. linux sed 命令的用法

    原文  http://blog.chinaunix.net/uid-24426415-id-77244.html ------------------------------------------- ...

  9. 阿牛的EOF牛肉串-记忆化搜索或动态规划

    C - 阿牛的EOF牛肉串 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submi ...

  10. JAVA学习(三):Java基础语法(变量、常量、数据类型、运算符与数据类型转换)

    Java基础语法(变量.常量.数据类型.运算符与数据类型转换) 1.变量 Java中.用户能够通过指定数据类型和标识符来声明变量.其基本的语法为: DataType identifier; 或 Dat ...