题目
给你一个图,告诉你走多少步,每一个点作为起点的可能性是相同的,走某一个点的概率也是相同的,问所有走法中不仅过某一个点的概率是多少。
思路:
dp[i][j]代表走d步到达j点的概率;
我们可以知道dp[0][j] = 1.0 / n (还没走,以每个点为起点的概率是一样的);
然后我们还可以知道dp[i][j] = dp[i - 1][v[j][k]] / v[j].size(); 就是第i步到j,等于第i-1步到j的临边的概率并除以临边的数量的叠加;
在所有过程中我们要除掉我们所要求的点;
那么dp[d][1] + dp[d][2] ......就是经过d步到达所有点的概率加起来(全都不包括我要求的点),就得到所有不经过该点的概率了;
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
double dp[10100][60];
vector<int> edge[60];
int n,m,d;
double solve(int x)
{
dp[0][0]=1;
double ans=0;
for(int i=0; i<=d; i++)
{
for(int j=0; j<=n; j++)
{
if(j==x) continue;
double p=1.0/edge[j].size();
for(int k=0; k<edge[j].size(); k++)
{
dp[i+1][edge[j][k]]+=dp[i][j]*p;
}
}
ans+=dp[i+1][x];
}
return 1.0-ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&d);
for(int i=0; i<=n; i++)
edge[i].clear();
for(int i=0; i<m; i++)
{
int a,b;
scanf("%d%d",&a,&b);
edge[a].push_back(b);
edge[b].push_back(a);
}
for(int i=1; i<=n; i++)
edge[0].push_back(i);
double ans;
for(int i=1; i<=n; i++)
{
memset(dp,0,sizeof(dp));
printf("%.10f\n",solve(i));
}
}
return 0;
}