[NOI2005]聪聪与可可
XII.[NOI2005]聪聪与可可
这题一个naive的思路是设表示时刻老鼠在位置的概率,然后求出表示猫时刻前抓到老鼠的概率(因为如果时刻猫可以抓到老鼠,则时刻猫一定仍可以抓到老鼠;而时刻猫能抓到老鼠的位置只有可能距猫的起点),最后差个分就能得出答案。
但是我们发现猫并不能保证所有的位置都能抓到——举例子来说,我们有这样一个样例:
猫从出发,第一时刻到达;但是,如果老鼠此时走到了,虽然到的距离,但是猫仍不能一次抓到老鼠。
所以我们不得不考虑一种新的想法,即记录下猫和鼠的位置,求出此时它期望多少轮能够捉到鼠。
我们设表示猫在时,鼠在时的期望次数;我们再设表示此时猫下一步会走到哪里。可以通过地预处理出来距离数组,再地预处理出来数组表示猫走一步的目标,然后通过预处理出来得出。
则有:
,如果;
,如果猫能直接从走到;
否则,设这里有一条边,则有
凭直觉发现这不可能有环;故直接记忆化搞掉即可。
时间复杂度。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,dis[1010][1010],nex1[1010][1010],nex2[1010][1010],cat,mouse;
double f[1010][1010];
bool vis[1010][1010];
vector<int>v[1010];
void bfs(int S){
queue<int>q;
memset(dis[S],0x3f,sizeof(dis[S])),dis[S][S]=0;
q.push(S);
while(!q.empty()){
int x=q.front();q.pop();
for(auto y:v[x])if(dis[S][y]==0x3f3f3f3f)dis[S][y]=dis[S][x]+1,q.push(y);
}
}
double dfs(int x,int y){
if(vis[x][y])return f[x][y];
vis[x][y]=true;
double &now=f[x][y];
if(x==y)return now=0;
if(nex2[x][y]==-1)return now=1;
x=nex2[x][y];
for(auto z:v[y])now+=dfs(x,z)+1;
now+=dfs(x,y)+1;
now/=int(v[y].size()+1);
return now;
}
int main(){
scanf("%d%d",&n,&m);
scanf("%d%d",&cat,&mouse);
for(int i=1,x,y;i<=m;i++)scanf("%d%d",&x,&y),v[x].push_back(y),v[y].push_back(x);
for(int i=1;i<=n;i++)bfs(i);
// for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)printf("%d ",dis[i][j]);puts("");}
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){
if(dis[i][j]==0x3f3f3f3f)continue;
if(dis[i][j]<=1){nex1[i][j]=-1;continue;}
int mp=-1;
for(auto k:v[i])if(mp==-1||dis[mp][j]>dis[k][j]||dis[mp][j]==dis[k][j]&&mp>k)mp=k;
nex1[i][j]=mp;
}
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){
if(dis[i][j]==0x3f3f3f3f)continue;
if(nex1[i][j]==-1||nex1[nex1[i][j]][j]==-1){nex2[i][j]=-1;continue;}
nex2[i][j]=nex1[nex1[i][j]][j];
}
// for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)printf("%d ",nex2[i][j]);puts("");}
// for(int i=1;i<=n;i++)printf("%d ",dis[i]);puts("");
printf("%.3lf\n",dfs(cat,mouse));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?