首页 > 其他分享 >AcWing1024 -- 记忆化搜索 & 天梯赛

AcWing1024 -- 记忆化搜索 & 天梯赛

时间:2023-03-27 14:23:01浏览次数:59  
标签:AcWing1024 fa -- 短路 我们 int 天梯 节点 分支

1. 题目描述

2022年天梯赛正赛 \(DIV2\)



2. 思路

首先认真读题,题目说的是每次送完外卖之后不必返回起点。
另外,需要送外卖的点是逐个添加,每添加一次都要算一次最短路。

我们假设一次性把所有点都添加了,此时如何求最短路呢?
如果说我们可以一条路走到黑而无需回头走的话,那么此时最短路就是最深的那个点距离根的距离。
否则,例如样例中添加 \(5,6,2,3\) 之后,有多个分支,我们必须回头走,但是,有一个分支我们是不需要回头走的,还记得前面说的吗,“每次送完外卖之后不必返回起点。”。

出于贪心的角度,我们肯定希望不需要回头走的那个分支尽可能的长,这样我们少走的距离肯定更少。

因此,最短路就等于:走过的路径之和 * 2 - 最长的分支长度

好的,我们已经解决了如何找到答案,但是题目中的点不是一次性全部给出的啊,难道每给一个点我们都需要遍历一次树来查找路经之和以及最长的分支长度吗?其实是不必的,我们可以保存之前查找过的信息,下次搜索时直接使用,所谓“记忆化搜索”



3. 代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;

int n, m, fa[N];
int sum;    // 保存走过的路经之和
int maxn;   // 保存走过的最长分支
int f[N];   // 保存某个节点到根节点的距离

// 返回 u 到根节点的路径长
// 求该长度的同时,我们便可以维护 sum 
int dfs(int u)
{
    // 如果是根节点或者已经搜索过了
    if(fa[u] == -1 || f[u] != -1) return f[u];
    // 走一步到父节点
    sum ++ ;
    // 记忆化
    return f[u] = 1 + dfs(fa[u]);
}

int main()
{
    // 因为根到根的距离为0,所以我们要将f设置为非-1的特殊值
    // 以方便我们判断某个点有没有走过
    memset(f, -1, sizeof f);
    cin >> n >> m;
    for(int i = 1; i <= n; i ++ )  
    {
        cin >> fa[i];
        // root
        if(fa[i] == -1) f[i] = 0;
    }
    for(int i = 1; i <= m; i ++ )
    {
        int x;  cin >> x;
        // 对于每个点,我们查找它走过的路径之和
        // 注意这里需要去重
        // 另外,从根开始找路径是找不到的
        // 我们必须从当前节点往根遍历
        maxn = max(maxn, dfs(x));
        cout << sum * 2 - maxn << endl;
    }
    return 0;
}

4. 参考

Reference1

标签:AcWing1024,fa,--,短路,我们,int,天梯,节点,分支
From: https://www.cnblogs.com/ALaterStart/p/17261305.html

相关文章

  • MySql随笔记基础
    XAMPP使用shell命令 每个数据库对应一个子文件夹 mysql进入mySQL的命令-urootuserroot登录用户-uroot-ppassword登录密码-p123showdatabases显示数据......
  • 同一个类转换异常处理
    程序运行异常用一个类出现同一个类报cannotbecastto,不能强制转换,服务器错误500java.xxxx.xxxxcannotbecasttojava.xxxx.xxxx处理方法可能是SpringBoot热部......
  • vue组件化开发---插槽的使用
    插槽基本介绍在开发中,我们会经常封装一个个可复用的组件:前面我们会通过props传递给组件一些数据,让组件来进行展示;但是为了让这个组件具备更强的通用性,我们不能将组件中......
  • datax同步oracle到mysql例子
     1.json文件[root@host135script]#moreoracle2mysql.json{"job":{"content":[{"reader":{......
  • 如何编写一个arrange 函数
    /***@description链式调用的方法*@param{*}taskIs*@example*arrange('arrage').waitFirst(2).do('吃西瓜').do('吃西瓜2').execute()*@returns{exec......
  • 多线程
    1、概念线程:线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。进程:进程是程序的基本执行实体。多线程:有了多线程,就可以让程序同......
  • first-letter 伪元素
    first-letter伪元素"first-letter"伪元素用于向文本的首字母设置特殊样式:实例p:first-letter{color:#ff0000;font-size:xx-large;}注意: "first-letter"伪......
  • 计算机组成原理
    计算机系统1.硬件2.软件系统软件:用来管理计算机系统应用软件:为执行特定任务而编写相关概念解释微处理器:CPU机器字长:32/64位处理器,计算机一次整数运算所能处理......
  • :first-line 伪元素
    :first-line伪元素"first-line"伪元素用于向文本的首行设置特殊样式。在下面的例子中,浏览器会根据"first-line"伪元素中的样式对p元素的第一行文本进行格式化:实......
  • python+playwright 学习-39.登录页面滑动解锁(ActionChains)
    前言登录页面会遇到滑块解锁,滑动解锁的目的就是为了防止别人用代码登录(也就是为了防止你自动化登录),有些滑动解锁是需要去拼图这种会难一点。有些直接拖到最最右侧就可以......