HDU 5001 Walk

题意:给你一个无向图,你从任意一个起点出发,每到一个节点,随机去往与该节点相邻的一个节点,问你走了d步之后,不经           过每一个点的概率是多少。

思路:枚举目标点,用dp[i][j]表示第i步第一次到达第j个点的概率。注意 是第一次。

     然后再用  1-∑dp[i][pos]   pos为目标点。重点是,对于每一步下的循环,如果第j个点为目标点就跳过它,

        否则第i+1步到达第k个点的概率就加上第i步到达第j个点的概率再除以第j个点的度数。还有,注意dp数组的初始化。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const int MAXN=55;
const int MAXD=11000;
vector<int> G[MAXN];
double dp[MAXD][MAXN];
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,d,u,v,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&d);
        for(int i=0;i<=n;i++)
            G[i].clear();
        while(m--)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }

        for(int dis=1;dis<=n;dis++)
        {
            double ans=0;
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++)
                dp[0][i]=1.0/n;
            for(int i=0;i<d;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(j==dis)
                        continue;
                    else
                    {
                        for(int k=0;k<G[j].size();k++)
                            dp[i+1][G[j][k]]+=dp[i][j]/G[j].size();
                    }
                }
            }
            for(int i=0;i<=d;i++)
                ans+=dp[i][dis];
            printf("%.10f\n",1-ans);
        }
    }
    return 0;
}
View Code

 

posted on 2015-09-01 11:08  onlyAzha  阅读(213)  评论(0编辑  收藏  举报

导航