http://acm.hdu.edu.cn/showproblem.php?pid=5001
给定n个点m条边的无向图问从任意点出发任意走d步,从不经过某个点的概率
本想先算路过每个点的概率然后用1减去这个概率 但是由于可以重复路过 所以无法判断是不是第一次经过这个点
所以我们应该直接做不路过的概率 即类似bfs的一步步走 如果走到了要计算的点就停下来 意思就是除了要计算概率的那个点不能走以外 其他都能走 最后统计下概率的和就是不路过这个点的概率
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <queue> #include <vector> #include<map> #include <iostream> #include <algorithm> using namespace std; #define RD(x) scanf("%d",&x) #define RD2(x,y) scanf("%d%d",&x,&y) #define clr0(x) memset(x,0,sizeof(x)) typedef long long LL; typedef pair<int,int> pii; const double INF=2100000000; int n,m,D; vector<int> g[55]; double dp[55][10050]; int main() { int _,u,v; RD(_); while(_--){ RD(n);RD2(m,D); for(int i = 1;i <= n;++i) g[i].clear(); for(int i = 1;i <= m;++i){ RD2(u,v); g[u].push_back(v); g[v].push_back(u); } double ans; for(int i = 1;i <= n;++i){ clr0(dp); ans = 0; for(int d = 0;d <= D;++d){ if(!d){ for(int j = 1;j <= n;++j)if(i != j){ dp[j][0] = 1.0/(double)n; } } else{ for(int j = 1;j <= n;++j)if(i != j){ for(int k = 0;k < g[j].size();++k){ int m = g[j][k]; if(m != i) dp[j][d] += dp[m][d-1]/(double)g[m].size(); } } } } for(int j = 1;j <= n;++j)if(i != j){ ans += dp[j][D]; } printf("%.9lf ",ans); } } return 0 ; }