博客
关于我
poj 2057 树形DP,数学期望
阅读量:804 次
发布时间:2023-03-03

本文共 2416 字,大约阅读时间需要 8 分钟。

为了求解蜗牛从树根爬行到房子的最短期望距离,我们需要计算每个节点的最短爬行距离 die[i] 和成功爬行距离 win[i]。以下是详细的分析和解决方案:

问题分析

  • 定义

    • die[i]:以节点 i 为根节点,无法找到房子时的最短爬行距离。
    • win[i]:以节点 i 为根节点,找到房子时的最短爬行距离。
  • 节点属性

    • pos[i]:节点 i 是否有毛毛虫(Y)。
    • vec[i]:节点 i 的子节点列表。
  • 爬行规则

    • 每个分支和枝末为节点,节点间距离为1。
    • 毛毛虫会告知蜗牛路径信息,影响爬行顺序。
  • 解决思路

  • 递归计算

    • 使用深度优先搜索(DFS)递归遍历树结构。
    • 对于每个节点,分别计算 die[i]win[i]
  • 计算方法

    • die[i]:从节点 i 出发,无法找到房子的最短路径。
      • 如果 i 没毛毛虫,die[i] = die[j] + 1ji 的子节点。
      • 如果 i 有毛毛虫,die[i] 为所有子节点的 die[j] + 1 中的最小值。
    • win[i]:从节点 i 出发,找到房子的最短路径。
      • 如果 i 没毛毛虫,win[i] = die[j] + 1ji 的子节点。
      • 如果 i 有毛毛虫,win[i] 为所有子节点的 win[j] 中的最小值。
  • 优化访问顺序

    • 使用比较函数 cmp(a, b),优先处理更可能成功的子节点,减少重复路径。
  • 解决代码

    #include 
    #include
    #include
    using namespace std;const int maxn = 1010;int pos[maxn];int snode[maxn];int die[maxn];int win[maxn];int n;vector
    > vec;void init() { memset(pos, 0, sizeof(pos)); memset(snode, 0, sizeof(snode)); memset(die, 0, sizeof(die)); memset(win, 0, sizeof(win)); char ps; int pre; for (int i = 1; i <= n; ++i) { vec[i].clear(); } for (int i = 1; i <= n; ++i) { scanf("%d %c%*c", &pre, &ps); if (pre == -1) continue; vec[pre].push_back(i); pos[i] = (ps == 'Y') ? 1 : 0; }}int cmp(int a, int b) { return (die[a] + 2) * snode[b] < (die[b] + 2) * snode[a];}void dfs(int x) { int len = vec[x].size(); for (int i = 0; i < len; ++i) { int j = vec[x][i]; if (!cmp(j, i)) continue; if (pos[j] == 0) { die[j] = die[x] + 1; win[j] = die[j]; } else { die[j] = die[x] + 1; if (pos[j]) { win[j] = win[j] ? min(win[j], win[x] + 1) : win[x] + 1; } else { win[j] = die[j]; } } dfs(j); if (pos[j]) { if (win[j] < win[x]) { win[x] = win[j]; } } else { if (die[j] + 1 < die[x]) { die[x] = die[j] + 1; } } }}void main() { init(); for (int i = 1; i <= n; ++i) { if (!snode[i]) continue; dfs(i); }}

    代码解释

  • 初始化

    • init() 函数初始化所有数组和向量,读取输入数据并构建树结构。
  • 比较函数

    • cmp(a, b) 根据 diesnode 值确定访问顺序,优先处理更可能成功的分支。
  • 递归DFS

    • dfs(x) 处理节点 x,计算 die[x]win[x]
    • 遍历所有子节点 j,根据 pos[j] 判断是否有毛毛虫,更新 diewin
    • 递归处理子节点 j,更新当前节点的 windie
  • 主函数

    • 初始化后,对每个节点调用 dfs 计算最短距离。
  • 通过以上方法,我们可以高效地计算蜗牛从树根爬行到房子的最短期望距离,确保在处理毛毛虫的询问顺序时,减少重复路径,优化整体性能。

    转载地址:http://guxfk.baihongyu.com/

    你可能感兴趣的文章