[NOI2005]聪聪与可可 题解 期望
题目传送门
题意
-
给定一个无向图,以及
\text{A} \text{B} 初始位置。 -
-
-
每次
\text{A} 比\text{B} 先走。 -
问
\text{A} 追上\text{B} 的期望时间。
Sol
期望类题目。
首先看这个
那么我们不妨先暴力跑出
可以用
由于边数小,离
我们以
可得对于
同时若
分析每次暴力往下跑后,可得通项
显然可以记忆化搜索。
于是便能完成问题。
/*
***
还要继续努力
成为一名烤咕学家哦
***
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e3+5;
const double eps=1e-5;
ll n,e,c,m,p[N][N],dis[N][N];
double f[N][N];
vector<ll> w[N];
template <typename T> void rd(T &x){
ll fl=1;x=0;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') fl=-fl;
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
x*=fl;
}
void wr(ll x){
if(x<0) x=-x,putchar('-');
if(x<10) putchar(x+'0');
if(x>9) wr(x/10),putchar(x%10+'0');
}
double dp(ll u,ll v){
if(u==v) return f[u][v]=0.0;
if(p[u][v]==v||p[p[u][v]][v]==v) return f[u][v]=1.0;
if(f[u][v]!=0.0) return f[u][v];
for(ll k=0;k<w[v].size();k++) f[u][v]+=dp(p[p[u][v]][v],w[v][k]);f[u][v]+=dp(p[p[u][v]][v],v);
f[u][v]/=(double)(w[v].size()+1);f[u][v]+=1.0;
return f[u][v];
}
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
rd(n);rd(e);rd(c);rd(m);
for(ll i=0,u,v;i<e;i++) rd(u),rd(v),w[u].push_back(v),w[v].push_back(u);
memset(dis,-1,sizeof(dis));
for(ll i=1;i<=n;i++){
queue<ll> q;q.push(i);dis[i][i]=0;
while(!q.empty()){
ll u=q.front();q.pop();
for(ll j=0;j<w[u].size();j++)
if(dis[i][w[u][j]]==-1) dis[i][w[u][j]]=dis[i][u]+1,q.push(w[u][j]);
}
}
memset(p,0x3f,sizeof(p));
for(ll i=1;i<=n;i++)
for(ll k=0;k<w[i].size();k++)
for(ll j=1;j<=n;j++)
if(dis[i][j]==dis[w[i][k]][j]+1) p[i][j]=min(p[i][j],w[i][k]);
cout<<fixed<<setprecision(3)<<dp(c,m);puts("");
return 0;
}