C++---树形DP---树的中心(每日一道算法2023.7.19)

注意事项:
本题为"树形DP—树的最长路径"的近似题,同时涉及到 单链表模拟邻接表存储图 的操作,建议先理解那篇文章。

题目:
给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。
请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。

输入格式
第一行包含整数 n。
接下来 n−1 行,每行包含三个整数 ai,bi,ci,表示点 ai 和 bi 之间存在一条权值为 ci 的边。

输出格式
输出一个整数,表示所求点到树中其他结点的最远距离。

数据范围
1≤n≤10000,1≤ai,bi≤n,1≤ci≤105

输入:
5 
2 1 1 
3 2 1 
4 3 1 
5 1 1
输出:
2
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;

const int N = 10010, M = N*2, INF = 0x3f3f3f3f;   //无向边,M开点数的两倍
int n;
int h[N], e[M], ne[M], w[M], idx = 0;       //邻接表链表模拟
int d1[N], d2[N], p1[N], up[N];       //d1[i]为点i向下的最长路径的长度,d2[i]为次长路径的长度,p1[i]为点i的最长路径的下一个点是谁,u[i]为点i向上的最长路径的长度

//经典的邻接表-链表模拟 存储图/树
void add(int a, int b, int c) {
    e[idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx++;
}

//向下找最长路径和次长路径,用子节点信息更新父节点,并返回最长路径的长度
int dfs_down(int u, int father) {
    //遍历所有点,找到从u点向下走的最长路径和次长路径
    for (int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if (j == father) continue;               //向下找,所以不能向父节点找路

        int d = dfs_down(j, u) + w[i];    //求出从u点向j点走,再向其他点走的最长路径的长度

        //判断当前的这条路径是否能替换最长路径或者次长路径,并更新p1数组进行记录最长路径的下一个点
        if (d >= d1[u]) {
            d2[u] = d1[u], d1[u] = d;
            p1[u] = j;
        }
        else if (d > d2[u]) {
            d2[u] = d;
        }
    }
    return d1[u];
}

//还是向下遍历树,但这次是用当前点u来更新点j的状态,也就是父节点信息更新子节点
void dfs_up(int u, int father) {
    for (int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if (j == father) continue;

        //如果点u的最长路径的下一个点(p1[u])是点j,那么就不能选最长路径来更新
        if (p1[u] == j) up[j] = max(up[u], d2[u]) + w[i];
        else up[j] = max(up[u], d1[u]) + w[i];

        dfs_up(j, u);
    }
}

int main() {
    //读入
    cin >> n;
    memset(h, -1, sizeof h);   //所有链表初始都指向-1
    for (int i = 0; i<n-1; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);    //无向边,那就a->b,b->a双向边即可
    }

    dfs_down(1, -1);
    dfs_up(1, -1);

    //枚举所有点的向上和向下的情况,求出最短距离
    int res = INF;
    for (int i = 1; i<=n; i++) {
        res = min(res, max(d1[i], up[i]));
    }
    cout << res;
}

思路:
这个题和"树的最长路径"很相似,“树的最长路径”是只要求出 点向下的最长和次长路径的长度相加即可,
而这道题多了一种向上找路径的可能,那么不妨举个例子,还是和上题一样,将整个树“拎起来”,类似拓扑结构:
请添加图片描述
接下来以p1代表点一,p2代表点2
假设现在遍历到了p2,那如何求出p2到所有点的最长路径的长度?

条件1. 从当前节点往下,直到子树中某个叶节点的最长路径。
将p2能到的每条路(除了父节点p1)都dfs一遍即可。

条件2. 从当前节点往上走到其父节点,再从其父节点出发且不回到该节点的最长路径。
还是从上往下遍历,但这次是用p1来更新p2,首先判断p1的向下最长路径是否经过p2,
1.如果未经过p2,那么就可以直接更新p2的向上最长路径,也就是p1到p2的距离+p1的最长向下路径的长度,
2.如果经过p2,那么就说明p1的向下最长路径经过p2,也就不能使用最长路径了,这也就是为什么需要求出次长路径的原因,接着更新p2的向上最长路径,也就是p1到p2的距离+p1的次长向下路径的长度。

对所有的点进行上述两个条件的计算,再取max即为这个点到所有点的最长距离,
再将每个点的这个结果取min,即为树中某节点到其他所有节点最远距离最近的答案。

如果有所帮助请给个免费的赞吧~有人看才是支撑我写下去的动力!

声明:
算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/42723.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp查看ios打包后的Info.plist文件

最近在用 uni 开发 ios 的时候给项目添加了自定义的 Info.plist 文件&#xff0c;但是打包后发现并没有生效&#xff0c;才有了查看打包后的 Info.plist 文件想法。 HBuilderX3.6.5起&#xff0c;支持直接在应用项目中配置 iOS 平台的 Info.plist 和 资源文件&#xff08;Bundl…

C# List 详解二

目录 5.Clear() 6.Contains(T) 7.ConvertAll(Converter) ,toutput> 8.CopyTo(Int32, T[], Int32, Int32) 9.CopyTo(T[]) 10.CopyTo(T[], Int32) C# List 详解一 1.Add(T)&#xff0c;2.AddRange(IEnumerable)&#xff0c;3.AsReadOnly()&…

RabbitMQ集群搭建

说明&#xff1a;集群&#xff0c;不管是Redis集群&#xff0c;还是MQ集群&#xff0c;都是为了提高系统的可用性&#xff0c;使系统不至于因为Redis、MQ宕机而崩溃。本文介绍RabbitMQ集群搭建&#xff0c;RabbitMQ集群分为以下三类&#xff1a; 普通集群 镜像集群 仲裁队列 …

循环链表的实现

循环链表简介 简单来说&#xff0c;单链表像一个小巷&#xff0c;无论怎么样最终都能从一端走到另一端&#xff0c;循环链表则像一个有传送门的小巷&#xff0c;因为循环链表当你以为你走到结尾的时候&#xff0c;其实你又回到了开头。循环链表和非循环链表其实创建的过程以及…

程序员基础知识—IP地址

文章目录 一、什么是IP地址二、IP地址的分类三、子网掩码 一、什么是IP地址 IP地址就像我们需要打电话时的电话号码一样&#xff0c;它用来标识网络中的一台主机&#xff0c;每台主机至少有一个IP地址&#xff0c;而且这个IP地址是全网唯一的。IP地址由网路号和主机号两部分组…

Elasticsearch/Enterprise Search/Kibana安装记录

目录 Elasticsearch的安装导入 elasticsearch PGP密钥 安装使用APT安装手动下载安装 启动elasticsearch安全功能重新配置节点以加入现有集群启用系统索引的自动创建功能运行Elasticsearch(在systemd下)检查Elasticsearch是否正在运行Elasticsearch配置外网访问 第三方包安装ela…

Python学习(十六)柱状图

zdaPython学习&#xff08;十四&#xff09;折线图开发_yikuaidabin的博客-CSDN博客 案例数据资源 ↑ """演示基础柱状图的开发 """ from pyecharts.charts import Bar from pyecharts.options import LabelOpts # 使用Bar构建基础柱状图 bar …

【网络】socket——TCP网络通信 | 日志功能 | 守护进程

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 上篇文章中本喵介绍了UDP网络通信的socket代码&#xff0c;今天介绍TCP网络通信的socket代码。 TCP &a…

深度理解 Spring AOP

一、什么是AOP(面向切面编程)&#xff1f;&#x1f349; AOP 为 Aspect Oriented Programming 的缩写&#xff0c;意思为面向切面编程&#xff0c;是通过预编译方式 和运行期 动态代理 实现程序功能的统一维护的一种技术。 AOP &#xff08;面向切面编程&#xff09;是 OOP&a…

深度理解 Spring IOC

Spring容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息&#xff0c;并在Spring容器中生成一份相应的Bean配置注册表&#xff0c;然后根据这张注册表实例化Bean&#xff0c;装配好Bean之间的依赖关系&#xff0c;为上层应用提供准备就绪的运行环境。 Bean缓存池&…

OJ练习第143题——二叉树展开为链表

二叉树展开为链表 力扣链接&#xff1a;114. 二叉树展开为链表 题目描述 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终…

postman批量执行请求,通过json传参

1、创建请求 "authUid":"{{authUid}}", 加粗为需要替换的参数 2、组装JSON 可通过Excel自动填充功能构造数据 [ {"authUid":"18700000001"}, {"authUid":"18725929202"} ] 3、批量执行请求配置 4、然后start r…

PuTTY连接服务器报错Connection refused

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Cloudreve搭建云盘系统,并实现随时访问

文章目录 1、前言2、本地网站搭建1.环境使用2.支持组件选择3.网页安装4.测试和使用5.问题解决 3、本地网页发布1.cpolar云端设置2.cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了&#xff0c;各互联网大厂也纷纷加入战局&#xff0c;一时间公…

RabbitMQ惰性队列使用

说明&#xff1a;惰性队列是为了解决消息堆积问题&#xff0c;当生产者生产消息的速度远高于消费者消费消息的速度时&#xff0c;消息会大量的堆积在队列中&#xff0c;而队列中存放的消息数量是有限的&#xff0c;当超出数量时&#xff0c;会造成消息的丢失。而扩容队列&#…

uniapp app运行到ios详细流程

uniapp运行到IOS真机调试&#xff08;windows系统&#xff09; 工具步骤1.首先数据线连接电脑和手机2.右键点击桌面上的HBuilder&#xff0c;打开文件所在位置3.打开HBuilder编辑器里要运行的项目&#xff0c;点击运行>运行到手机或模拟器>运行到IOS APP基座>勾选你的…

LangChain大型语言模型(LLM)应用开发(五):评估

LangChain是一个基于大语言模型&#xff08;如ChatGPT&#xff09;用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口&#xff0c;可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互&#x…

【每日一题】——C - Standings(AtCoder Beginner Contest 308 )

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析

一、 空间数据获取与制图 1.1 软件安装与应用讲解 1.2 空间数据介绍 1.3海量空间数据下载 1.4 ArcGIS软件快速入门 1.5 Geodatabase地理数据库 二、 ArcGIS专题地图制作 2.1专题地图制作规范 2.2 空间数据的准备与处理 2.3 空间数据可视化&#xff1a;地图符号与注记 …

十一、正则表达式详解:掌握强大的文本处理工具(三)

文章目录 &#x1f340;贪婪模式&#x1f340;应用的场景&#x1f340;总结 &#x1f340;非贪婪模式&#x1f340;应用的场景&#x1f340;总结 &#x1f340;贪婪模式与非贪婪模式在爬虫的应用&#x1f340;转义字符&#x1f340;正则表达式常见函数 &#x1f340;贪婪模式 在…