在一个魔法森林里,住着一只聪明的小猫聪聪和一只可爱的小老鼠可可。虽 然灰姑娘非常喜欢她们俩,但是,聪聪终究是一只猫,而可可终究是一只老鼠, 同样不变的是,聪聪成天想着要吃掉可可。

一天,聪聪意外得到了一台非常有用的机器,据说是叫 GPS,对可可能准确 的定位。有了这台机器,聪聪要吃可可就易如反掌了。于是,聪聪准备马上出发, 去找可可。而可怜的可可还不知道大难即将临头,仍在森林里无忧无虑的玩耍。 小兔子乖乖听到这件事,马上向灰姑娘报告。灰姑娘决定尽快阻止聪聪,拯救可 可,可她不知道还有没有足够的时间。

整个森林可以认为是一个无向图,图中有 N 个美丽的景点,景点从 1 至 N 编号。小动物们都只在景点休息、玩耍。在景点之间有一些路连接。

当聪聪得到 GPS 时,可可正在景点 M(M≤N)处。以后的每个时间单位,可可 都会选择去相邻的景点(可能有多个)中的一个或停留在原景点不动。而去这些地方所发生的概率是相等的。假设有 P 个景点与景点 M 相邻,它们分别是景点 R、 景点 S,……景点 Q,在时刻 TT 可可处在景点 M,则在( T+1 )时刻,可可有 1/(1 +P) 的可能在景点 R,有 1/(1 +P) 的可能在景点 S,……,有 1/(1 +P) 的可能在景点 Q,还有1/(1 +P)的可能停在景点 M。

我们知道,聪聪是很聪明的,所以,当她在景点 C 时,她会选一个更靠近 可可的景点,如果这样的景点有多个,她会选一个标号最小的景点。由于聪聪太 想吃掉可可了,如果走完第一步以后仍然没吃到可可,她还可以在本段时间内再 向可可走近一步。

在每个时间单位,假设聪聪先走,可可后走。在某一时刻,若聪聪和可可位 于同一个景点,则可怜的可可就被吃掉了。

灰姑娘想知道,平均情况下,聪聪几步就可能吃到可可。而你需要帮助灰姑 娘尽快的找到答案。

链接 🔗

「NOI2005」聪聪与可可

题解 ❓

N<=1000N<= 1000
可以通过BFS预处理出两点之间的距离(O(N2)O(N^2))
然后可以预处理出聪聪在xx点,可可在yy点时,xx下一步走哪
然后后面的就可以通过记忆化搜索统计期望了

  1. 聪聪当前回合能到达可可的位置,则期望为1
  2. 聪聪可可在同一位置,期望为0
  3. 否则考虑可可下一步的所有点v,对于聪聪所在的点x,统计所有x到v的期望

代码

const int N = 1e3+10;
V G[N];
ll vis[N],dis[N][N],net[N][N],h[N][N];
double dp[N][N];
double dfs(ll x,ll y)
{
    if(h[x][y]) return dp[x][y];
    h[x][y] = 1;
    if(x == y) return dp[x][y] = 0;
    ll u = net[x][y],v = net[u][y];
    dp[x][y] = 1.0;
    if(u == y | v == y) return dp[x][y];
    for(auto z:G[y]) dp[x][y] += dfs(v,z) / (1.0 * G[y].size() +1.0);
    dp[x][y] += dfs(v,y) / (1.0 * G[y].size() +1.0);
    return dp[x][y];
}
int main()
{
//    __IN;__OUT;
    ll n,m,s,t;
     RLL2(n,m);RLL2(s,t);
     FOR(i,1,m)
     {
         ll x,y;RLL2(x,y);
         G[x].pb(y); G[y].pb(x);
     }
     MM(dis,0x3f);
     FOR(i,1,n)
     {
         queue<ll> que;
         MM(vis,0);
         que.push(i);dis[i][i] = 0;
         vis[i] = 1;
         while(!que.empty())
         {
             ll x = que.front(); que.pop();
             for(auto v:G[x])
             {
                 if(vis[v]) continue;
                 vis[v] = 1; dis[i][v] = dis[i][x]+1;
                 que.push(v);
             }
         }
     }
     MM(net,0x3f);
     FOR(x,1,n)
        for(auto v:G[x])
            FOR(z,1,n)
                if(dis[x][z] == 1+dis[v][z])
                    net[x][z] = min(net[x][z],v);
    printf("%.3lf",dfs(s,t));
    return 0;
}