其实是很简单的概率DP,看样例的时候因为没读懂0.00000,根本就没有想。
三维数组dp[i][step][x]代表:没有经过i点的概率,走了step步,现在在x点的概率。
第一维可以省去。
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int INF =0x3f3f3f3f;
const int maxn= 50 ;
const int maxd=10000 ;
vector<int > G[maxn+5];
int n,m,d;
void init()
{
for(int i=1;i<=n;i++) G[i].clear();
}
inline void add_edge(int x,int y)
{
G[x].push_back(y);
G[y].push_back(x);
}
double dp[maxd+10][maxn+5];
int main()
{
int T,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&d);
d++;
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add_edge(x,y);
}
for(int i=1;i<=n;i++)
{
for(int step=1;step<=d;step++)
{
for(int x=1;x<=n;x++) if(x!=i)
{
if(step==1) {dp[step][x]=1.0/n;continue;}
dp[step][x]=0;
double &ans=dp[step][x];
for(int j=0;j<G[x].size();j++)
{
int y=G[x][j];
if(y==i) continue;
int num=G[y].size();
ans+=dp[step-1][y]*(1.0/num) ;
}
}
}
double ret=0;
for(int x=1;x<=n;x++) if(x!=i)
{
ret+=dp[d][x];
}
printf("%.10f\n",ret);
}
}
return 0;
}