首页 > 代码库 > HDU 5001 Walk
HDU 5001 Walk
题意:
连通无向图 随机选起点 随机乱走 可以重复走点 问 每个点有多大几率不被路过
思路:
一看就是DP题…
但是开始的时候陷入了僵局 我是想先算路过每个点的概率然后用1减去这个概率 但是由于可以重复路过 所以无法判断是不是第一次经过这个点
所以我们应该直接做不路过的概率 即类似bfs的一步步走 如果走到了要计算的点就停下来 意思就是除了要计算概率的那个点不能走以外 其他都能走 最后统计下概率的和就是不路过这个点的概率
PS:
这题一定要用邻接表 我一开始看这图可能是完全图而且n只有50 就用了邻接矩阵 然后就T了 换邻接表就1218MS
代码:
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<set> #include<vector> #include<cassert> using namespace std; typedef long long LL; #define Q 401 #define N 51 #define M 10001 #define inf 2147483647 #define mod 1000000007 #define lowbit(x) (x&(-x)) int t, n, m, p, tot; int head[N], d[N]; double dp[M][N]; struct edge { int v, next; } ed[N * N * 2]; void add(int u, int v) { ed[tot].v = v; ed[tot].next = head[u]; head[u] = tot++; } int main() { int i, j, k, f; double ans; scanf("%d", &t); while (t--) { scanf("%d%d%d", &n, &m, &p); for (i = 1; i <= n; i++) { head[i] = -1; d[i] = 0; } tot = 0; for (i = 1; i <= m; i++) { scanf("%d%d", &j, &k); d[j]++; d[k]++; add(j, k); add(k, j); } for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { if (i != j) dp[0][j] = 1.0 / n; else dp[0][j] = 0; } for (f = 1; f <= p; f++) { for (j = 1; j <= n; j++) dp[f][j] = 0; for (j = 1; j <= n; j++) { if (i == j) continue; for (k = head[j]; ~k; k = ed[k].next) dp[f][ed[k].v] += dp[f - 1][j] / d[j]; } } ans = 0; for (j = 1; j <= n; j++) { if (i != j) ans += dp[p][j]; } printf("%f\n", ans); } } return 0; }
HDU 5001 Walk
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。