【SPOJ-TOMJERRY】Tom and Jerry【概率DP】【记忆化搜索】

来源:互联网 发布:在线编程怎么用 编辑:程序博客网 时间:2024/04/29 18:07

就是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);}}


0 0
原创粉丝点击