hdu 5001 Walk (概率dp)

题意:

n个点m条边构成无向图。每一步可以从一个点走向与其连接的另一个点。每一步的概率都相同。对于每个点而言,考虑所有步数为d的旅行路线,求不经过它的概率。(不经过该点的路线总数 / 所有路线总线)

数据范围: n<=50, n-1<=m<=n*(n-1)/2, 1<=d<=10000


解法:

dp[i][k]:不经过结点x,第k步到达结点i的概率。初始时dp[i][0] = 1.0 / n  (想象开始时从一个虚拟结点走向各点算第0步)

枚举去掉结点,算dp[i][k]之和.


代码:

#include <cstdio>
#include <iostream>
#include <string.h>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <stack>
using namespace std;
int const uu[4] = {1,-1,0,0};
int const vv[4] = {0,0,1,-1};
typedef long long ll;
int const maxn = 50005;
int const inf = 0x3f3f3f3f;
ll const INF = 0x7fffffffffffffffll;
double eps = 1e-10;
double pi = acos(-1.0);
#define rep(i,s,n) for(int i=(s);i<=(n);++i)
#define rep2(i,s,n) for(int i=(s);i>=(n);--i)
#define mem(v,n) memset(v,(n),sizeof(v))
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1

int T,n,m,d;
vector<int> graph[55];
double dp[55][10005]; //node x cost k steps


void dpCalc(int x){ //remove node x
    mem(dp,0.0);
    rep(i,1,n){
        if(i!=x) dp[i][0] = 1.0/n;
        else dp[i][0] = 0.0;
    }
    rep(k,0,d-1)
        rep(i,1,n){
            if(i!=x){
                int L = graph[i].size();
                rep(j,0,L-1) dp[graph[i][j]][k+1] += (dp[i][k]/L);
            }
        }
    double ans = 0.0;
    rep(i,1,n){
        if(i!=x) ans += dp[i][d];
    }
    printf("%.10lf
",ans);
}

int main(){
    cin >> T;
    while(T--){
        scanf("%d%d%d",&n,&m,&d);

        rep(i,1,n) graph[i].clear();

        while(m--){
            int a,b;
            scanf("%d%d",&a,&b);
            graph[a].push_back(b);
            graph[b].push_back(a);
        }
        rep(i,1,n){
            dpCalc(i);
        }
    }
}

  



原文地址:https://www.cnblogs.com/fish7/p/3985284.html