您的位置:首页 > 其它

hdu 5001 Walk (概率dp)

2014-09-20 23:22 357 查看
题意:

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\n",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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: