HDU 5001 Walk(暴力+概率DP)

来源:互联网 发布:svd推荐算法实现 编辑:程序博客网 时间:2024/04/30 05:25

题目链接:传送门 


题意:

给定一个无向图,起点任意选走过的点也可以走,限定你走k步,然后求每个点没有走过的概率。


分析:

设dp[u][d]表示走了d步到达点u的概率,dp[u][0]=1/n,dp[u][d] = sigma(dp[v][d-1] / du[v]).du[v]代表点v的度数。


代码如下: 

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <vector>using namespace std;const int N = 55;const int maxn = 10010;double dp[N][maxn];vector<int > vc[N];double ans[N];int n,m,d;double solve(int u) {    memset(dp,0,sizeof(dp));    for(int i=1; i<=n; i++) {        dp[i][0]=1.0/(double)n;    }    double ans = 0;    ans+=dp[u][0];    for(int i=1;i<=d;i++){        for(int j=1;j<=n;j++){            if (u == j) continue;            double p = 1.0/vc[j].size();            for(int k=0;k<vc[j].size();k++)                dp[vc[j][k]][i]+=dp[j][i-1]*p;        }        ans+=dp[u][i];    }    return 1.0-ans;}int main() {    int t;    scanf("%d",&t);    while(t--) {        scanf("%d%d%d",&n,&m,&d);        for(int i=0; i<N; i++)            vc[i].clear();        for(int i=0; i<m; i++) {            int u,v;            scanf("%d%d",&u,&v);            vc[u].push_back(v);            vc[v].push_back(u);        }        for(int i=1; i<=n; i++)            printf("%.6lf\n",solve(i));    }    return 0;}


0 0