传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1415

水题没话说,预处理出两个点的最短路,再记忆化搜索就行了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <list>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn = 1010;
list <int> edge[maxn];
double f[maxn][maxn][2];
int dis[maxn][maxn];
int n, m, s, t;
queue <int> q;
void bfs(int x) {
    dis[x][x] = 0;
    q.push(x);
    while(!q.empty()) {
        int t = q.front();
        q.pop();
        for(list <int> :: iterator p = edge[t].begin(); p != edge[t].end(); p ++) {
            if(dis[x][t] + 1 < dis[x][*p]) {
                dis[x][*p] = dis[x][t] + 1;
                q.push(*p);
            }
        }
    }
    return;
}
int get(int x, int y) {
    int d = INF, ans = INF;
    for(list <int> :: iterator p = edge[x].begin(); p != edge[x].end(); p ++) {
        if(dis[*p][y] < d || (dis[*p][y] == d && *p < ans)) {
            d = dis[*p][y];
            ans = *p;
        }
    }
    return ans;
}
double dp(int x, int y, int l) {
    if(f[x][y][l] != -1) return f[x][y][l];
    if(x == y) return 0;
    if(l) {
        int nxt = get(x, y);
        if(nxt != y) nxt = get(nxt, y);
        f[x][y][l] = dp(nxt, y, 0) + 1;
    } else {
        double res = 0, cnt = 0;
        for(list <int> :: iterator p = edge[y].begin(); p != edge[y].end(); p ++) {
            res += dp(x, *p, 1);
            cnt += 1;
        }
        res += dp(x, y, 1);
        cnt += 1;
        f[x][y][l] = res / cnt;
    }
    return f[x][y][l];
}
int main() {
    scanf("%d%d", &n, &m);
    scanf("%d%d", &s, &t);
    int u, v;
    for(int i = 1; i <= m; i ++) {
        scanf("%d%d", &u, &v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    memset(dis, 0x3f, sizeof(dis));
    for(int i = 1; i <= n; i ++) {
        bfs(i);
    }
    for(int i = 0; i < maxn; i ++) {
        for(int j = 0; j < maxn; j ++) {
            for(int k = 0; k < 2; k ++) {
                f[i][j][k] = -1;
            }
        }
    }
    printf("%.3lf\n", dp(s, t, 1));
    return 0;
}