就是NOI2005聪聪和可可。
论文题,见《浅析竞赛中一类数学期望问题的解决方法》
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1005, maxq = 10000;
int n, m, head[maxn], cnt, p[maxn][maxn], dis[maxn], du[maxn], q[maxq];
double dp[maxn][maxn];
struct _edge {
int v, next;
} g[maxn << 1];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline void add(int u, int v) {
g[cnt] = (_edge) {v, head[u]};
head[u] = cnt++;
}
void bfs(int x) {
int h = 0, t = 0; q[t++] = x;
for(int i = 1; i <= n; i++) dis[i] = -1;
dis[x] = 0;
while(h != t) {
int u = q[h++];
for(int i = head[u]; ~i; i = g[i].next)
if(!~dis[g[i].v]) {
dis[g[i].v] = dis[u] + 1;
p[g[i].v][x] = u;
q[t++] = g[i].v;
} else if(dis[g[i].v] == dis[u] + 1) p[g[i].v][x] = min(p[g[i].v][x], u);
}
}
double dfs(int u, int v) {
if(dp[u][v] != -1) return dp[u][v];
if(u == v) return dp[u][v] = 0.0;
if(p[u][v] == v || p[p[u][v]][v] == v) return dp[u][v] = 1.0;
double ans = dfs(p[p[u][v]][v], v);
for(int i = head[v]; ~i; i = g[i].next) ans += dfs(p[p[u][v]][v], g[i].v);
ans /= (du[v] + 1.0);
ans += 1.0;
return dp[u][v] = ans;
}
int main() {
int T = iread();
while(T--) {
n = iread(); m = iread();
for(int i = 1; i <= n; i++) {
head[i] = -1, du[i] = 0;
for(int j = 1; j <= n; j++) p[i][j] = dp[i][j] = -1;
}
cnt = 0;
int P = iread(), Q = iread();
for(int i = 1; i <= m; i++) {
int x = iread(), y = iread();
du[x]++; du[y]++;
add(x, y); add(y, x);
}
for(int i = 1; i <= n; i++) bfs(i);
double ans = dfs(P, Q);
printf("%.3lf\n", ans);
}
}