hdu5001 Walk 概率dp

//给一个无向图 , 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 ;
const int maxm = 10010 ;
const int maxn = 60 ;
double dp[maxm][maxn] ;
double outdegree[maxn] ;
double p[maxn] ;
vector<int>vec[maxn] ;
int main()
{
   // freopen("in.txt" ,"r" , stdin) ;
    int T ;
    int m , n, d ;
    scanf("%d" ,&T) ;
    while(T--)
    {
        scanf("%d%d%d" ,&n , &m , &d) ;
        memset(p , 0 , sizeof(p)) ;
        for(int i = 1;i <= n;i++)
        vec[i].clear() ;
        for(int i = 1;i <= m;i++)
        {
            int a , b ;
            scanf("%d%d" ,&a ,&b) ;
            vec[a].push_back(b) ;
            vec[b].push_back(a) ;
        }
        for(int s = 1;s <= n;s++)
        {
            memset(dp , 0 , sizeof(dp)) ;
            for(int i = 1;i <= n;i++)
            dp[0][i] = 1.0/(double)n ;
            double ans = 0 ;
            for(int i = 1;i <= d;i++)
            for(int j = 1;j <= n;j++)
            {
                if(j == s)continue ;
                for(int k = 0;k < vec[j].size() ;k++)
                {
                    int v = vec[j][k] ;
                    if(v == s)continue ;
                    dp[i][j] += dp[i-1][v]/(double)vec[j].size();
                }
            }
            dp[0][s] = 1.0/(double)n ;
            for(int j = 1;j <= n;j++)
            p[s] += dp[d][j] ;
        }
        for(int i = 1;i <= n;i++)
        printf("%lf\n" , p[i]) ;
    }
    return 0 ;
}





你可能感兴趣的:(hdu5001 Walk 概率dp)