HDU -- 5001 Walk(2014鞍山网络赛E)(概率)

来源:互联网 发布:java没有返回值的方法 编辑:程序博客网 时间:2024/04/29 16:24

题意:给一个无向图,要在这个图上走d步,每个点被选为起点的概率相同,每个点到和它相邻的点的概率相同。求d步都没走到某个点的概率。

http://acm.hdu.edu.cn/showproblem.php?pid=5001

感觉很简单的样子,但是比赛的时候就是连样例都过不了QAQ。。。

看别人的题解说是每次删掉一的点,走d步到达其他点的概率之和就是d步都不到这个点的概率(ans[i] = ∑p[d][i])。

但是这是为什么呢?

首先,p[i][j]表示第i步走到j的概率,p[i][j] = ∑p[i - 1][v] / e;(v是和j相邻的顶点,e是以v为起点的边数)

一下子想不出来ans[i] = ∑p[d][i]

我们先想只走一步。这样就变成了前1步不走cur的概率 = 第一步走到其他点的概率和。这显然成立。。。

然后我们再想要走两步的情况:前2步不走cur的概率 = 第2步走到其他点的概率和。想到这时已经保证了第1步不走cur,相当于保证了前2步都不走cur!

所以等式成立。

推广到走d步。前d步都不走到cur的情况下走到其他点的概率之和就是ans[cur]!

#include <map>#include <set>#include <cmath>#include <queue>#include <stack>#include <cstdio>#include <string>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef double DB;typedef long long ll;typedef unsigned long long ull;typedef pair<int, int> PII;#define pb push_back#define MP make_pair#define lson l, m, rt << 1#define rson m + 1, r, rt << 1 | 1const DB eps = 1e-8;const int inf = 0x3f3f3f3f;const int mod = 10000007;const int maxn = 2000 + 10;int T, n, m, d;DB p[11111][55], ans[55];vector<int> V[55];int main(){    scanf("%d", &T);    while(T--){        scanf("%d%d%d", &n, &m, &d);        for(int i=1; i<=n; i++) V[i].clear();        for(int i=1; i<=m; i++){            int a, b;            scanf("%d%d", &a, &b);            V[a].pb(b);            V[b].pb(a);        }        for(int cur=1; cur<=n; cur++){///枚举不走的点            memset(p, 0, sizeof(p));            for(int i=1; i<=n; i++) p[0][i] = 1.0 / n;///选每个点做起点的概率都是1/n            for(int i=1; i<=d; i++){                for(int j=1; j<=n; j++) if(j != cur){///不从cur走                    for(unsigned k=0; k<V[j].size(); k++){///枚举所有和j相邻的点                        int v = V[j][k];                        p[i][v] += p[i - 1][j] / (DB)V[j].size();///p[i][v]表示第i步到v的概率                    }                }            }            ans[cur] = 0.0;            for(int i=1; i<=n; i++) if(i != cur){                ans[cur] += p[d][i];            }        }        for(int i=1; i<=n; i++) printf("%.10f\n", ans[i]);    }    return 0;}

比赛的时候我们是分别从每个点出发,计算第i步到j的概率,再把每步不到j的概率乘起来,就是每步都不到j的概率。

0 0