bzoj1415
记忆化搜索
这是一个dag,肯定会抓住的,所以可以记忆化搜索
然后预处理出p[i][j]表示i,j位置怎么走,记忆化搜索就行了
#include<bits/stdc++.h> using namespace std; const int N = 1010; struct edge { int nxt, to; } e[N << 1]; int n, m, a, b, cnt = 1; int head[N], d[N][N], p[N][N]; double deg[N], dp[N][N]; void link(int u, int v) { e[++cnt].nxt = head[u]; head[u] = cnt; e[cnt].to = v; } double dfs(int a, int b) { if(a == b) return 0; if(p[a][b] == b) return 1; if(p[a][b] <= n && p[p[a][b]][b] == b) return 1; if(dp[a][b] != -1) return dp[a][b]; int to = p[p[a][b]][b]; dp[a][b] = (dfs(to, b) + 1.0) / (deg[b] + 1.0); for(int i = head[b]; i; i = e[i].nxt) dp[a][b] += (dfs(to, e[i].to) + 1.0) / (deg[b] + 1.0); return dp[a][b]; } int main() { scanf("%d%d%d%d", &n, &m, &a, &b); for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) dp[i][j] = -1.0; for(int i = 1; i <= m; ++i) { int u, v; scanf("%d%d", &u, &v); link(u, v); link(v, u); deg[u] += 1.0; deg[v] += 1.0; } memset(p, 0x3f3f, sizeof(p)); memset(d, -1, sizeof(d)); for(int i = 1; i <= n; ++i) { d[i][i] = 0; queue<int> q; q.push(i); while(!q.empty()) { int u = q.front(); q.pop(); for(int j = head[u]; j; j = e[j].nxt) if(d[i][e[j].to] == -1) { d[i][e[j].to] = d[i][u] + 1; q.push(e[j].to); } } for(int j = 1; j <= n; ++j) { int mn = 0x3f3f3f3f; for(int k = head[j]; k; k = e[k].nxt) { if(mn > d[i][e[k].to]) { mn = d[i][e[k].to]; p[j][i] = e[k].to; } else if(mn == d[i][e[k].to]) p[j][i] = min(p[j][i], e[k].to); } } } printf("%.3f\n", dfs(a, b)); return 0; }