首页 > 其他分享 >简单树上问题

简单树上问题

时间:2024-02-04 10:33:27浏览次数:23  
标签:结点 子树 最大值 大值 DFS 问题 简单 树上 dp

1. 树的重心

树的重心是无根树上的一个应用。满足以下性质的点 \(u\) 为树的重心:

删除结点 \(u\) 即与它相连的边,如果在剩下的两棵或多课子树中最大子树的结点数最少,那么 \(u\) 就是树的重心。

例1 POJ-3107 翻译

本题的教父就是树的重心。接下来分析方法。

首先是暴力法。枚举一个点,设它为重心,计算出删除它后剩下的子树中最大子树的结点数来判断是否合法。计算节点数时可以用 DFS。这样时间复杂度为 \(\mathcal{O}(N^2)\),不能通过本题。

只需要做一次 DFS 就可以求解。

设结点 \(1\) 为根。用 \(S_i\) 表示结点 \(i\) 的子树的结点数,这样 \(S\) 可以用一次 DFS 求出。那么去掉结点 \(u\) 后,\(u\) 的所有子节点会成为单独的树,它们的大小在 DFS 的过程中已经求出;\(u\) 的父节点也会成为一棵单独的树,它的大小即为 \(n-S_u\)。这样就可以在一次 DFS 的同时求出树的重心了。

代码

2. 树的直径

树的直径是指树上最远的两点之间的距离。有两种方法求树的直径:

  1. 两次 DFS 或 BFS。

  2. 树形 DP。

这两种方法的时间复杂度都为 \(\mathcal{O}(N)\)。

方法 \(1\) 可以记录路径,但不能处理负边权。

方法 \(2\) 可以处理负边权,但不能记录路径。

  1. 两次 DFS 或 BFS

例1 洛谷-U283565

DFS 或 BFS 可以处理没有负边的树。方法很简单:

  • 在树上找任意一点为起点,用 DFS 求出到这个点距离最远的点 \(s\)。

  • 接下来以 \(s\) 为起点,用 DFS 求出到 \(s\) 最远的点 \(t\)。

  • \(s,t\) 即为树的直径的两个端点。

代码

  1. 树形 DP

设 \(dp_u\) 表示 \(u\) 的子树中距离 \(u\) 最远的点的距离。那么状态转移方程如下:

\(dp_u=\max(dp_v+w)\),其中 \(v\) 是与 \(u\) 相连的点,\(w\) 是 \(u\) 到 \(v\) 边的权值。

再用 \(f_u\) 表示经过点 \(u\) 的最长路径长度。那么状态转移方程如下:

\(f_u=\max(dp_u+dp_v+w)\),其中 \(dp_u\) 不包括 \(dp_v\) 子树的长度。

那么这颗树的直径即为 \(\max \limits_{i=1}^n f_i\)。

其实 \(f\) 不用单独开数组,只需要在每次计算出后取最大值即可。

那怎么计算不包括子树 \(dp_v\) 的 \(dp_u\) 呢?

可以发现,子树 \(u\) 内的最大值即为所有的 \(dp_v+w\) 的最大值与次大值之和。那么又分两种情况:

  • 最大值在次大值之前被计算

在计算到次大值时,\(dp_u\) 为最大值,\(dp_u+dp_v+w\) 即为子树 \(u\) 最大值。

  • 次大值在最大值之前被计算

在计算到次大值时,\(dp_u\) 为次大值,\(dp_u+dp_v+w\) 即为子树 \(u\) 最大值。接下来 \(dp_u\) 就会更新成最大值。

于是就不用再排序了。

例2 洛谷-U81904

本题边权有负数,应使用树形 DP。

代码

3. 习题

Baekjoon-1167 翻译

本题链式前向星似乎不能通过,但邻接表可以通过。建单向边。

Baekjoon-1967 翻译

本题数据规模较小且没有负权值。建单向边。

标签:结点,子树,最大值,大值,DFS,问题,简单,树上,dp
From: https://www.cnblogs.com/lrxmg139/p/18005717

相关文章

  • Linux服务器升级GLIBC失败导致shell不可用的问题解决经历
    转自https://blog.csdn.net/u010549608/article/details/126281354?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170696599716800182728626%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170696599716800182728626&biz_i......
  • Windows 下 LaTex 超简单地安装使用(MikTeX + VSCode)
    写这篇是因为我找了一晚上教程,结果发现基本上都过时了,现在的版本下根本不需要任何复杂的操作,干脆自己写一个免得后来人再崩溃。参考及主要内容来源,可以说我后半部分内容基本就是翻译(?安装LaTex主流的分发版本应该就是TeXLive和MikTeX了,这里使用MikTex——TeXLive太大了......
  • 简单方法使 kernel32.dll 发生重定位
    简单方法使kernel32.dll发生重定位系统启动后kernel32.dll在每个进程的加载地址都相同。。。。吗?相信很多人都知道这个,因为这个是远程线程注入的基础,类似的还有user32.dll之类的系统dll。不过这个概念是错误的,或者说它在绝大多数时候是正确的因为通常来说这些系统dll默......
  • RubyMine 2023: 让Ruby开发变得更简单 mac/win版
    JetBrainsRubyMine2023是一款专为Ruby开发者打造的强大集成开发环境。这个版本致力于提供卓越的性能、强大的功能和一流的智能代码编辑支持,帮助您更高效地开发高质量的Ruby应用程序。→→↓↓载RubyMine2023mac+win版首先,RubyMine2023提供了对最新Ruby和相关技术的全面支......
  • dremio LivenessService 服务简单说明
    LivenessService是dremiobackend提供的一个http服务,提供了live(存活)以及metrics服务此服务在dremio集群中的每个节点上都会运行,以下是一些说明一些特点服务使用了jetty与官方dac的backend是不太一样,默认使用了jersey框架默认基于本地回环地址bind同时bind的端口是......
  • vue2.x的项目运行问题(export,set)
    Windows系统修改package.json文件:"scripts":{"serve":"setNODE_OPTIONS=--openssl-legacy-provider&&vue-cli-serviceserve","build":"setNODE_OPTIONS=--openssl-legacy-provider&&vue-cli-s......
  • 问题:黄金大米呈金黄色是因为转入了( )
    问题:黄金大米呈金黄色是因为转入了()A:叶黄素基因;B:β胡萝卜素基因;C:Bt基因;D:维生素D合成酶基因参考答案如图所示......
  • 关于java时间类型和格式化到微秒问题
    常规的问题此处略,因为网络上到处都是,这里主要讨论三个问题:1.数据库的时间戳类型(含微秒)对应java的什么类型java的常见时间类型比较多:java.util.Datejava.sql.Datejava.sql.Timestampjava.util.Calendarjava.time.LocalDatejava.time.LocalTimejava.time.LocalDateTime......
  • JDBC的简单封装
    1、dataSource.propertiesdriver=oracle.jdbc.driver.OracleDriverurl=jdbc:oracle:thin:@localhost:1521:orclusername=usernamepassword=password2、代码示例packagecom.example;importjava.io.IOException;importjava.io.InputStream;importjava.sql.Connection;imp......
  • 金蝶云星空业务对象同步更新问题
     一、协同开发平台允许:多应用多个数据中心,多应用一个数据中心,一个应用多个数据中心。 二、在不同的应用下可以使用 【同步业务对象到数据中心】功能:该功能就是拉取当前应用在svn管理的最新版本更新到当前的数据中心。   【更新数据中心业务对象到应用......