dp[i][j] += dp[i-1][j] * (1.0/num[j] );
dp[i][j]是指在第i步走到点j的概率,每次排除一个点,然后算取不经过这个点在最后一步走到所有点的概率,然后求和,就是不经过这一点的概率
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#define MAX 57
#define N 10007
using namespace std;
int t,n,m,d,u,v;
struct Edge
{
int v,next;
}e[MAX*MAX*2];
int head[MAX];
int num[MAX];
double dp[MAX][N];
int cc = 0;
void add ( int u , int v )
{
e[cc].v = v;
e[cc].next = head[u];
head[u] = cc++;
}
int main ( )
{
scanf ( "%d" , &t );
while ( t-- )
{
memset ( head , -1 , sizeof ( head ));
memset ( num , 0 , sizeof ( num ) );
cc = 0;
scanf ( "%d%d%d" , &n , &m , &d );
for ( int i = 0 ; i < m ; i++ )
{
scanf ( "%d%d" , &u , &v );
add ( u , v );
add ( v , u );
num[u]++;
num[v]++;
}
for ( int p = 1 ; p <= n ; p++ )
{
for ( int i = 0 ; i < MAX ; i++ )
for ( int j = 0 ; j < N ; j++ )
dp[i][j] = 0.0;
for ( int u = 1 ; u <= n ; u++ ) dp[u][0] = 1.0/(n*1.0);
for ( int i = 1 ; i <= d ; i++ )
for ( int u = 1 ; u <= n ; u++ )
{
if ( u == p ) continue;
for ( int k = head[u] ; k != -1 ; k = e[k].next )
{
int v = e[k].v;
if ( v == p ) continue;
// cout << "YES: " << v << " " << i-1 << endl;
dp[u][i] += dp[v][i-1]*1.0/(num[v]*1.0);
// cout << dp[u][i] << endl;
}
}
double ans = 0.0;
for ( int u = 1 ; u <= n ; u++ )
{
if ( u == p ) continue;
// cout << "YES : " << dp[u][d] << endl;
ans += dp[u][d];
}
printf ( "%.9lf\n" , ans );
}
}
}