http://acm.hdu.edu.cn/showproblem.php?pid=5001
给你一个图,你可以任意从一个点出发,走k步,每步的概率都是等价的。问你不到达某个点的概率。。、
思路:我tm。完全不会这种玩法。
解释看代码。
注意:求走j步到达i的时候,在求步数小于k的时候,也不能让这些点到过u点(u就是当前计算概率的点,因为如果到达过了,那么就算到过了,而我们算的 到达其他点,而完全没有经过u的概率。)
//给一个无向图 , 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 ;
/* 概率dp入门题?门在哪呢。
dp[u][i][j]。从u开始出发,经过j步走到了
i点,
所以题目求得 到不了的概率就是
dp[u][*][j]的概率。()
而计算这个概率的方法。就是求出他
k点之后到达其他点的概率、
*/
const int maxn=60;
vector<int>G[60];
int m,n,k;
int du[60];
double dp[60][10005];
double ans[60];
int solve(int x,int k){
for(int i=1;i<=m;i++){
dp[i][k]=0;
for(int j=0;j<G[i].size();j++){
int to=G[i][j];
if(to==x) continue;
dp[i][k]+=dp[to][k-1]/(1.0*du[to]);
}
}
}
int main()
{ int t,a,b;
scanf("%d",&t);
while(t--){
memset(du,0,sizeof(du));
memset(ans,0,sizeof(ans));
for(int i=0;i<maxn;i++)
G[i].clear();
scanf("%d%d%d",&m,&n,&k);
for(int i=0;i<n;i++){
scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
du[a]++,du[b]++;
}
for(int i=1;i<=m;i++)
dp[i][0]=1.0/(1.0*m);
for(int i=1;i<=m;i++){
//枚举每个点作为到不了的。
for(int j=1;j<=k;j++){
solve(i,j);
}
for(int x=1;x<=m;x++){
if(x==i) continue;
ans[i]+=dp[x][k];
}
}
for(int i=1;i<=m;i++){
printf("%.12f\n",ans[i]);
}
}
return 0 ;
}