Codeforces - 839C - Journey(图论 + 概率 + 搜索、*1500)

839C - Journey(⇔源地址








tag

⇔图论、⇔概率、⇔搜索、⇔*1500


题意

在七大王国里有 \(n\) 个城市和 \(n-1\) 条道路,每条道路连接两个城市,并且通过这些道路我们可以从任何一个城市到达任何一个城市。

席恩和阿莎在第一个城市骑上马,他们要通过这些路开始一次旅行。但是有雾,所以他们看不见他们的马带他们去了哪里。当马抵达一个城市的时候(包括第一个城市),它会去跟当前这个城市相连的城市。但是这是一匹奇怪的马,它只去他们以前没有去过的城市。在每个城市,马以相同的概率移动去上述符合要求的城市,并且当没有这样的城市(可走)时,马就停下了。

每条路的长度都是 \(1\),旅行从城市 \(1\) 开始,问这次旅行的期望长度(旅行长度的期望值)是多少?你可以通过这个链接来阅读一些关于期望(平均)值的文字。


思路

错误思路

首先上来一看,显然的搜索题,我以为题目是要求解到到叶子节点平均经过的举例,所以直接一个 \(\tt dfs\) 求解深度加上一个 \(\tt topsort\) 提取叶子节点算平均值了,样例坑的离谱,跑起来完全没感觉到有问题,然后光荣的WA了。

正解

这是一道图论+概率 \(\tt DP\) 的题目,特此写博文记录一下。

我们知道,期望等于概率乘以值,这道题中:

  • 概率即为到达这个点的概率:已知某个点 \(i\) ,到达其子节点 \(son_i\) 的概率即为 \(\dfrac{P(i)}{子节点数量}\)
  • 值即为这个点的深度。

所以直接用一个 \(\tt dfs\) 来维护这两个东西即可,没有别的套路了。


AC代码

点击查看代码
namespace Geometry { //几何
    using ld = long double;
    const ld PI = acos(-1);
    const ld EPS = 1e-7;
    template <class T, class S> inline bool equal(T x, S y) {
        return x - y < EPS && x - y > -EPS;
    }
    //    cout << fixed << setprecision(12);
}
using namespace Geometry;
namespace G {
    vector<int> ver[N];
    int deg[N], d[N];
    ld ans;
    
    void add(int x, int y) {
        ver[x].push_back(y);
        ++ deg[y];
    }
    void dfs(int x, int fa, ld p) {
        int siz = 0;
        for (auto y : ver[x]) {
            if (y == fa) continue;
            ++ siz;
        }
        for (auto y : ver[x]) {
            if (y == fa) continue;
            d[y] = d[x] + 1;
            dfs(y, x, p / siz);
        }
        if (siz == 0) ans += p * d[x];
    }
}
signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    
    cout << fixed << setprecision(15);
    
    int n; cin >> n;
    for (int i = 1; i < n; ++ i) {
        int x, y; cin >> x >> y;
        G::add(x, y), G::add(y, x);
    }
    G::dfs(1, -1, 1);
    cout << G::ans;
    
    return 0;
}

错误次数:2

第一发思路如上,稀碎;第二发改进了一下 \(n=1\) 的情况。






文 / WIDA

  1. 成文
    首发于WIDA个人博客,仅供学习讨论
posted @ 2022-10-31 18:50  hh2048  阅读(44)  评论(0编辑  收藏  举报