HDU-5001 Walk (概率DP)

Problem Description

I used to think I could be anything, but now I know that I couldn‘t do anything. So I started traveling.

The
nation looks like a connected bidirectional graph, and I am randomly
walking on it. It means when I am at node i, I will travel to an
adjacent node with the same probability in the next step. I will pick up
the start node randomly (each node in the graph has the same
probability.), and travel for d steps, noting that I may go through some
nodes multiple times.

If I miss some sights at a node, it will
make me unhappy. So I wonder for each node, what is the probability that
my path doesn‘t contain it.

Input

The first line contains an integer T, denoting the number of the test cases.

For
each test case, the first line contains 3 integers n, m and d, denoting
the number of vertices, the number of edges and the number of steps
respectively. Then m lines follows, each containing two integers a and
b, denoting there is an edge between node a and node b.

T<=20,
n<=50, n-1<=m<=n*(n-1)/2, 1<=d<=10000. There is no
self-loops or multiple edges in the graph, and the graph is connected.
The nodes are indexed from 1.

Output

For each test cases, output n lines, the i-th line containing the desired probability for the i-th node.

Your answer will be accepted if its absolute error doesn‘t exceed 1e-5.

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

题目大意:给一张无根无向图(n个节点,m条边),每一步走哪一个儿子节点的概率相同(以哪个点为起点的概率也相同)。对于每个点,找出走完d步后走不到该点的概率。

题目分析:定义dp(s,u)表示不经过节点i(1<=i<=n)走了s步时,到达u点的概率。则根据加法原理,dp(s,son)=sum(dp(s-1,u)*f),其中 f 是u走到其儿子son的概率,f=1.0/(u的儿子个数)。题目要求分别输出不经过节点 i (1<=i<=n) 的答案,则DP n次即可。对于每次DP,根据加法原理,答案为ans=sum(dp(d,j)),其中,j不等于i。

注意:第一步是从起点开始的,而选择起点的过程不能算做一步。

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std;
vector<int>v[55];
int n,m,d,vis[10005][55];
double dp[10005][55];
void solve()
{
    for(int i=1;i<=n;++i){
        memset(dp,0,sizeof(dp));
        for(int j=1;j<=n;++j)
            dp[0][j]=1.0/n;
        for(int j=1;j<=d;++j){
            for(int start=1;start<=n;++start){
                if(i==start)
                    continue;
                int l=v[start].size();
                for(int k=0;k<l;++k)
                    dp[j][v[start][k]]+=dp[j-1][start]*1.0/l;
            }
        }
        double ans=0.0;
        for(int j=1;j<=n;++j)
            if(j!=i)
                ans+=dp[d][j];
        printf("%.10lf\n",ans);
    }
}
int main()
{
    int T,a,b;
    vector<int>::iterator it;
    scanf("%d",&T);
    while(T--)
    {
        memset(vis,0,sizeof(vis));
        scanf("%d%d%d",&n,&m,&d);
        for(int i=1;i<=n;++i)
            v[i].clear();
        while(m--)
        {
            scanf("%d%d",&a,&b);
            it=find(v[a].begin(),v[a].end(),b);
            if(it==v[a].end())
                v[a].push_back(b);
            it=find(v[b].begin(),v[b].end(),a);
            if(it==v[b].end())
                v[b].push_back(a);
        }
        solve();
    }
    return 0;
}

  

时间: 2024-08-30 10:55:28

HDU-5001 Walk (概率DP)的相关文章

hdu 5001 walk 概率dp入门题

Description I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling. The nation looks like a connected bidirectional graph, and I am randomly walking on it. It means when I am at node i, I will travel t

Hdu 5001 Walk 概率dp

Walk Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5001 Description I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling. The nation looks like a connected bid

hdu 5001 Walk(概率)

http://acm.hdu.edu.cn/showproblem.php?pid=5001 应该算是一道简单的概率题.想了两个多小时,结果越想越麻烦.开了一个三维数组,MLE了.. 最后借鉴实验室学长的思路,发现这样想很直观,正退就可以. 设dp[j][d]表示不能经过i点走了d步到达j点的概率.那么dp[j][d] = ∑ dp[k][d-1]/edge[k].size().那么不经过i点的概率为∑dp[j][D]. #include <stdio.h> #include <iost

HDU 5001 Walk(鞍山网络赛E题)

HDU 5001 Walk 题目链接 思路:枚举每个要经过的点,然后进行状态转移,状态为dp[i][j],状态表示当前在j的点,已经走了i步,每次转移的时候,不从这个枚举的点出发,这样就可以求出所有路径经过该点的概率p, 然后1 - p就是不经过的答案 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; con

hdu 4870 Rating(概率DP&amp;高数消元)

Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 714    Accepted Submission(s): 452 Special Judge Problem Description A little girl loves programming competition very much. Recently, she

HDU 4035Maze(概率DP)

HDU 4035   Maze 体会到了状态转移,化简方程的重要性 题解转自http://blog.csdn.net/morgan_xww/article/details/6776947 /** dp求期望的题. 题意: 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结点i都有3种可能: 1.被杀死,回到结点1处(概率为ki) 2.找到出口,走出迷宫 (概率为ei) 3.和该点相连有m条边,随机走一条 求:走出迷宫所要走的边数的期望值. 设 E[i]表示

HDU - 5001 Walk(概率dp+记忆化搜索)

Walk I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling. The nation looks like a connected bidirectional graph, and I am randomly walking on it. It means when I am at node i, I will travel to an ad

HDU 5001 Walk 求从任意点出发任意走不经过某个点的概率 概率dp 2014 ACM/ICPC Asia Regional Anshan Online

题意: 给定n个点m条边的无向图 问: 从任意点出发任意走d步,从不经过某个点的概率 dp[i][j]表示从不经过i点的前提下,走了d步到达j点的概率. #include <iostream> #include <cstdio> #include <string.h> #include <queue> #include <vector> #include <algorithm> #include <set> using n

[概率dp] hdu 5001 Walk

题意:n个点(1~n),m条边,走k次,双向边,每次随机走一条路,起点也随机,问不走到各个点的概率是多少. 思路: 概率dp[i][j][k] 前i步 走到j 走不到k的概率. 那么状态转移就是 j能走到的点,传递所有dp[i][j][k]的值乘上概率. 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"

HDU5001 Walk(概率DP)

A - Walk Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 5001 Description I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling. The nation loo