Description I used to think I could be anything, but now I know that I couldn‘t do anything. So I started traveling. Input The first line contains an integer T, denoting the number of the test cases. Output For each test cases, output n lines, the i-th line containing the desired probability for the i-th node. Sample Input 2 5 10 100 1 2 2 3 3 4 4 5 1 5 2 4 3 5 2 5 1 4 1 3 10 10 10 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 4 9 Sample Output 0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.0000000000 0.6993317967 0.5864284952 0.4440860821 0.2275896991 0.4294074591 0.4851048742 0.4896018842 0.4525044250 0.3406567483 0.6421630037 |
题目大意:在一幅图中,主人公随机选择一个点为起始点,然后每一步都是随机选择相邻点进行访问,一共走了d步。求各个点没有被访问的概率。
概率dp入门题,定义dp[u][i][j]:经过了j步之后落在i点且从来不经过u点的概率。最后对于各个点,从不经过它的概率就是dp[u][*][d]的和。
在实际操作过程中,可以把dp数组变成二维的,即变成dp[i][j]。
#include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; const int maxn = 55; int head[maxn],cur; struct Edge { int to; int next; } edge[maxn*2]; void init() { cur=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v) { edge[cur].to = v; edge[cur].next = head[u]; head[u] = cur++; } double dp[maxn][10005]; double ans[maxn]; int du[maxn],n; void cal_dp(int x,int d) { for(int u=1; u<=n; u++) { dp[u][d] = 0; if(u==x) continue; for(int e=head[u]; e!=-1; e=edge[e].next) { int v = edge[e].to; if(v==x) continue; dp[u][d] += dp[v][d-1]/du[v]; } } } int main() { int T,u,v,m,d; scanf("%d",&T); while(T--) { init(); memset(du,0,sizeof(du)); scanf("%d%d%d",&n,&m,&d); for(int i=0; i<m; i++) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); du[u]++; du[v]++; } for(int i=1; i<=n; i++) { dp[i][0] = 1.0/n; ans[i]=0; } for(int u=1; u<=n; u++) { for(int j=1; j<=d; j++) cal_dp(u,j); for(int v=1;v<=n;v++) ans[u] += dp[v][d]; } for(int i=1; i<=n; i++) { printf("%.10lf\n",ans[i]); } } }