题解
这道题目是我的第一道期望dp……期望dp高深莫测令人恐惧……
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 0x73f3f3f;
struct Edge {
int v, next;
} e[2010];
int N, E, s, m, num = 0, head[2010];
void add(int u, int v) {
num ++;
e[num].v = v;
e[num].next = head[u];
head[u] = num;
}
int q[1010], dis[1010], vis[1010], state[10010], road[1010][1010];
void spfa(int s) {
memset(dis, INF, sizeof(dis));
int h = 0, tail = 1;
state[1] = s, vis[s] = true, dis[s] = 0;
while(h < tail) {
h ++;
int u = state[h]; vis[u] = false;
for(int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if(dis[v] > dis[u] + 1) {
dis[v] = dis[u] + 1;
if(! vis[v]) {
tail ++;
state[tail] = v;
vis[v] = true;
}
}
}
}
}
double f[1010][1010];
double dfs(int s, int m) {
if(f[s][m]) return f[s][m];
if(s == m) return 0;
if(road[road[s][m]][m] == m || road[s][m] == m) return 1.0;
double ans = dfs(road[road[s][m]][m], m);//敌动我不动
for(int i = head[m]; i; i = e[i].next) {
int v = e[i].v;
ans += dfs(road[road[s][m]][m], v);
}//敌动我也动
return f[s][m] = ans / (q[m] + 1) + 1;//每种概率是相等的直接同除
}
int main() {
scanf("%d %d", &N, &E);
scanf("%d %d", &s, &m);
while(E --) {
int u, v;
scanf("%d %d", &u, &v);
q[u] ++, q[v] ++;
add(u, v); add(v, u);
}
for(int i = 1; i <= N; i ++) {
spfa(i);
for(int j = 1; j <= N; j ++) {
int mmax = INF;
for(int k = head[j]; k; k = e[k].next) {
int v = e[k].v;
if(dis[v] < mmax || (dis[v] == mmax && v < road[j][i])) {//小的走小的;相同的走标号小的
mmax = dis[v];
road[j][i] = v;
}
}
}
}
printf("%0.3lf", dfs(s, m));
}