hdu5001-概率dp&经典&tooyoung-Walk

http://acm.hdu.edu.cn/showproblem.php?pid=5001
给你一个图,你可以任意从一个点出发,走k步,每步的概率都是等价的。问你不到达某个点的概率。。、
思路:我tm。完全不会这种玩法。
解释看代码。
注意:求走j步到达i的时候,在求步数小于k的时候,也不能让这些点到过u点(u就是当前计算概率的点,因为如果到达过了,那么就算到过了,而我们算的 到达其他点,而完全没有经过u的概率。)

//给一个无向图 , n个节点,m条边
//每个节点为起点的概率相同
//问每个节点走d步后不经过这个节点的概率
//不经过这个节点的概率等于去掉该节点的图中走了d步到其他节点的和
//dp[i][j] 为走了i步到达j个节点的概率
//dp[i][j] = segma(dp[i-1][v])/vec[j].size()
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std ;
/* 概率dp入门题?门在哪呢。
dp[u][i][j]。从u开始出发,经过j步走到了
i点,
所以题目求得 到不了的概率就是
dp[u][*][j]的概率。()
而计算这个概率的方法。就是求出他
k点之后到达其他点的概率、
*/
const int maxn=60;
vector<int>G[60];
int m,n,k;
int du[60];
double  dp[60][10005];
double ans[60];
int solve(int x,int k){
     for(int i=1;i<=m;i++){
         dp[i][k]=0;
         for(int j=0;j<G[i].size();j++){
             int to=G[i][j];
             if(to==x) continue;
             dp[i][k]+=dp[to][k-1]/(1.0*du[to]);
         }
     }
}
int main()
{   int t,a,b;
    scanf("%d",&t);
    while(t--){
         memset(du,0,sizeof(du));
         memset(ans,0,sizeof(ans));
         for(int i=0;i<maxn;i++)
            G[i].clear();
         scanf("%d%d%d",&m,&n,&k);
         for(int i=0;i<n;i++){
             scanf("%d%d",&a,&b);
             G[a].push_back(b);
             G[b].push_back(a);
             du[a]++,du[b]++;
         }
         for(int i=1;i<=m;i++)
            dp[i][0]=1.0/(1.0*m);
         for(int i=1;i<=m;i++){
            //枚举每个点作为到不了的。
            for(int j=1;j<=k;j++){
                solve(i,j);
            }
            for(int x=1;x<=m;x++){
                if(x==i) continue;
                ans[i]+=dp[x][k];
            }
         }
         for(int i=1;i<=m;i++){
             printf("%.12f\n",ans[i]);
         }
    }
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值