Codeforces 686 D. Kay and Snowflake

要求$O(n)$求出以每个节点为根的重心。

考虑对于一个根节点$u$,其重心一定在【各个子树的重心到$u$】这条链上。这样就能够$O(n)$推出来了。证明起来难证易忘。不如记住树的重心的几条奇妙性质:

1. 以重心为根,各子树大小都不超过树的一半。

2. 已知一子树$v$的重心为$x$,则$v$父节点$u$的重心一定在$(x,u)$这条链上。

... 下次用到了再说

Codeforces 842 C. Ilya And The Tree

这是一道玄学的题目。可以根据每个点清不清0转移状态。如果该点清0,那么很容易,父亲一直到根节点都不允许清0了。如果该点清0,是不是能直接转移呢?并不行,这里我犯了一个错误,并不是先前答案越大,更新得到的当前答案也会更大。换句话说,不满足最优子结构的性质。因此我们需要用一个数据结构维护父亲节点到根之间有且仅有一个点不选时的所有状态。这样的状态不会多,因为一个数被更新的状态时很有可能重复的。当然,复杂度还是很玄学。

感觉这道题主要是为了练set……

Codeforces 813 C. The Tag Game

给出一棵树和两个人。一人从$x$开始逃,一人从根开始追,问最长能追多长时间追到(每秒一条边)

考虑x要么直接往下逃,要么往上走一段距离然后往下逃。一旦开始往下逃并且没被抓,就会逃到底。因此只需要维护每个点的高度和深度,然后枚举往下逃的点(一定在到根的链上)更新答案即可。

其实这道题目没有必要规定根。不规定根答案也是一样的。

Codeforces 337 D. Book of Evil

给出一颗树上的$m$个标记点,求有多少个树上的点满足距离所有标记点都小于等于$d$。

距离所有标记点都要小于等于$d$,可以转化为距离最远的标记点要小于等于$d$。由此问题转化为求出每个点到距离它最远的标记点的距离。

考虑使用树形DP。对于一个点$u$,我们可以把最远的标记点划分为几个区域。一,$u$的子树内;二,$u$的子树外。而$u$的子树外的又可以分为两个部分:$u$的父亲的子树外,$u$的父亲的子树(不包括$u$所在的)。前者可以直接转移,后者是子树问题(注意要维护次大值,因为有可能与$u$的子树重合)。

注意要特判没有标记点的情况!

Codeforces 219 D. Choosing Capital for Treeland

给出一棵树,给每条边规定一个方向。要选择一个点,按照边的方向走能到达所有点。可以花1的代价改变一条边的方向。问最小代价。

用树形DP来思考问题那么就只需要考虑父子之间的关系了。先DFS预处理出从根节点$rt$到所有点的代价。然后考虑如果要将根节点的一个子节点$u$作为起点,那么只要考虑$(rt,u)$这条边的方向就好了。至于如何将初始边的方向存下来,我们可以考虑给边一个权值。0代表是原始方向,1代表这是反向边。

Codeforces 212 E. IT restaurants

给出一棵树,规定一条边的两端要么染不同颜色,要么一端不染颜色。总共两种颜色,一个点最多只能染一种颜色。两种颜色都必须染至少一次。问最多有多少个能被染色。并输出在最大化的情况下,两种颜色的个数分别有哪些情况。

第一问显然$n-1$,也就是一个点不染作为过渡,其它全染。我们可以把这个不染的点看做根节点。那么各个子树内的颜色必定是一样的,转化为01背包问题。

枚举每个点,求出各个子树的大小。做一次背包。我们来考虑复杂度是多少。设每个点的访问的子树个数是$k_i$,那么时间复杂度是$O(\sum\limits_{i=1}^{n}nk_i)$,我们发现每条边恰好被访问两次,因此$\sum\limits_{i=1}^{n}k_i=2n$。因此复杂度是$O(n^2)$

Codeforces 161 D. Distance in Tree

求树上距离为$k$的点对个数($n \leq 50000, k \leq 500$)

显然要维护$f_{u,k}$表示$u$的子树内有多少点到$u$的距离为$k$。一个做法是每次在枚举两棵子树,再枚举$k$进行转移;或者利用树形背包;但这样的复杂度都不可行。

子树内做不了考虑向上走,这是我没有想到的。刚才的做法之所以不可行,是因为起点和终点都未知,导致增加了子树选择的枚举。不如枚举起点,然后暴力往上走$k$次进行转移。即$dp_u = \sum\limits_k f_{g,K-k}$。注意$f_{g,K-k}$包含了$(u,g)$这条路径上的,因此要减掉。所以$dp_u = \sum\limits_k f_{g,K-k}-f_{las,K-k-1}$.

然而一般做法是点分治……

[NOIp2018] Day1T3 赛道修建

给出一棵树,每条边最多只能属于一条赛道。问要修建$m$条赛道,最短赛道最长是多少。($n \leq 5*10^4$)

二分答案。问题转化为判定每条赛道长度都大于等于$mid$时能否构成$m$条或以上赛道。考虑对于任意一个节点$u$,经过它的赛道要么在子树内,要么从下面穿过它并向上延伸。我们发现以下说法是正确的

  • 能从下面穿过它的最多一条,否则就会在上面重叠;
  • 最多只能用子节点的两条延伸来拼赛道,不然不符合题意;
  • 如果明明能通过$u$在子树内构成赛道,不必将它拆掉而向上延伸,因为贡献都是1(这是个贪心);
  • 如果将u作为起点向下延伸能构成一条赛道,那么不必用它去跟别人拼成一条赛道,因为贡献都是1(这也是个贪心);
  • 在子树内凑出同样数量的赛道肯定越短越好,尽量留出长的贡献给上面。

于是我们维护一个节点的所有子节点中延伸上来的长度(没有向上延伸就是0),优先选择$\geq mid$的点直接作为一条赛道;然后开始用两条来拼——从最小的开始考虑,二分出一个能到达$mid$的最小值,拼一下,然后以此类推。

复杂度$O(nlog^2n)$

思想又难细节又多。真恐怖!

Codeforces 1153 D. Serval and Rooted Tree

给出一棵树,每个非叶节点有一个操作$min$或$max$。要求在总共的$k$个叶子上填互不相同的$1$~$k$的整数。非叶节点的值为对其子节点的值进行对应操作得到的值。求根节点可能的最大值。

好像看似每个子树不是独立的,而子树的根节点能达到的值在子树的所有叶节点中的最大排名确是可以独立的。事实上题目规定填$1$~$k$的整数是没有必要的,只要知道根节点能达到的值在所有叶节点中的排名就可以了。于是我们可以考虑维护$dp_u$表示子树$u$中根节点所能达到的最大排名。我们利用子节点来推父节点。

考虑最大值。设目前考虑节点$u$,节点$i$的大小是$sz_i$。$u$有$k_u$个子树。每一个子树有一个叶子数,可以想象一下——有$k_u$个队列起初是空的,我们要从大到小将数推入这些队列。对于子节点$v$,$dp_v$之前的部分是不可取的。问可取的部分中每个队列的最大值的最大值是多少。显然我们优先将数全部填入$dp_v$最小的那个队列里,就能获得最大排名$dp_v$了。由此$dp_u=min\{dp_v\}$

考虑最小值。我们要让各个队列的最大值中的最小值尽量大,也就是要尽量平均。我们无论如何先得把每个队列中取不到的部分填满。然后依次在每个队列填一个数。最小的那个就是最大值的最小值了。由此$dp_u=\sum\limits dp_v$

Codeforces 14 D. Two Paths

给出一棵树,边权为1,求两条点不相交的路径的长度乘积的最大值。($n \leq 200$)

正解很简单:枚举边,删掉,两边求直径。事实证明我实在想得有点多。这类问题可以作为一个模型——我们可以将没有交集的两个东西当做独立的来分别求解。

Codeforces 1156 D. 0-1-Tree

给出一棵树,边权为0或1。问有多少点对$(x,y)$满足其路径上边权单调递增。($n \leq 2*10^5$)

对于合法的点对,其间路径有三种情况:全0;全1;前半部分0后半部分1。我们可以将树按0与1缩点(边两端点的点都要缩进去),用并查集维护大小。考虑单独点内也就是所有的全0或全1的情况了。对于既有0又有1的情况,考虑一定有这个转折点,而这个转折点一定同属两个并查集。减一后(交点不算)相乘即可。

注意并查集在访问祖先的时候不能直接使用$f_u$,因为可能还没有进行路径压缩。必须要使用$find$。

Codeforces 1092 F. Tree with Maximum Cost

给出一棵树($n \leq 2*10^5$),有点权$a_i$,无边权。从$u$走到$v$代价$f_{u,v}=a_u * dist_{u,v}$。请选择一个$v$,使得$\sum\limits_{u}f_{u,v}$最小。

类似的题目以前做到过。首先这个代价的意义先理解一下:可以认为是从$u$出发到$v$上每条边的边权都是$a_u$。由此,我们可以先通过树上差分状物求出根节点的答案。然后由根节点向下推——每次令推的方向上那颗子树上所有路径缩短,其余全部增加即可。

总结

树形DP——先设定状态,然后考虑状态的转移。一般是由子节点推父节点,也有特殊情况是由父节点推向子节点,看题目怎么问。甚至还有的是子节点先推出根节点,根节点再推回来。注意分析复杂度,一般如果是直接转移的,那么时间复杂度就是状态数;也可以用$\sum\limits k_i=n-1$(边数)来理解。常见的要维护的信息有:深度,叶子数,离根最近的叶子深度。我们把不影响当前状态的东西看做一个整体来处理,这样思路比较清晰。有时候也可以把某些问题类比为较为熟悉的线性问题。

「树形结构 / 树形DP」总结的更多相关文章

  1. 「单调队列优化DP」P2034 选择数字

    「单调队列优化DP」P2034 选择数字 题面描述: 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入格 ...

  2. [HNOI2007]梦幻岛宝珠 「套路:分层 $DP$」

    显然直接 \(01\) 背包会超时并且超空间 套路:分层 \(DP\) 「考虑将每个子结构看作一层(也就是包含了不止 \(1\) 个物品的信息),并且大层不会对小层造成影响,可以考虑先进行每一层的自我 ...

  3. 「BZOJ 4565」「HAOI 2016」字符合并「区间状压DP」

    题意 给一个长度为\(n(\leq 300)\)的\(01\)串,每次可以把\(k(\leq 8)\)个相邻字符合并,得到新字符和一定分数,最大化最后的得分 题解 考虑设计dp:\(dp[S][i][ ...

  4. 「概率,期望DP」总结

    期望=Σ概率*权值 1. Codeforces 148-D 考虑用$f[i][j]$表示princess进行操作时[还剩有i只w,j只b]这一状态的存在概率.这一概率要存在,之前draw out的一定 ...

  5. Oracle 输出树形结构

    Oracle 输出树形结构 树形结构,根 select connect_by_root(cat.parentid) root,cat.id,cat.parentid,cat.name,cat.code ...

  6. 「SQL归纳」树形结构表的存储与查询功能的实现——通过路径方法(非递归)

    一.树形结构例子分析: 以360问答页面为例:http://wenda.so.com/c/ 我们通过观察URL,可以明确该页面的数据以树形结构存储,下面三块模块分别为: ①根节点 ②根节点的第一层子节 ...

  7. [牛客] [#1108 J] [树形结构] 买一送一

    2019牛客国庆集训派对day3 链接:https://ac.nowcoder.com/acm/contest/1108/J来源:牛客网 题意 ICPCCamp 有 n 个商店,用 $1,2,..., ...

  8. js文章列表的树形结构输出

    文章表设计成这样了 后端直接给了无任何处理的json数据,现在要前端实现树形结构的输出,其实后端处理更简单写,不过既然来了就码出来 var doclist = [{ "id": 1 ...

  9. GridView 树形结构分组的功能

    在“会飞的鱼”博客中看到GridView实现树形结构的代码,经过修改,添加了树形结构中的复选框功能,欢迎吐槽. 源地址:http://www.cnblogs.com/chhuic/archive/20 ...

随机推荐

  1. Java基础之 多线程

    一.创建多线程程序的第一种方式: 继承(extends) Thread类 Thread类的子类: MyThread //1.创建一个Thread类的子类 public class MyThread e ...

  2. [LeetCode] 1092. Shortest Common Supersequence

    LeetCode刷题记录 传送门 Description Given two strings str1 and str2, return the shortest string that has bo ...

  3. ESXi导出的CentOS7 ovf文件导入到workstation 无法打开GUI登录界面的问题解决方案

    1. 前几天将centos的机器导出为ovf 文件 然后使用 workstation 引入之后发现总是黑屏 然后有一个 横杠在闪 2. 解决办法是 修改centos的虚拟机配置文件,将显示器修改为这样 ...

  4. springboot工程启动时,报错:No bean named 'shiroFilter' available

    在启动Springboot项目时,报错:org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ' ...

  5. link标签中的integrity和crossorigin字段

    https://blog.csdn.net/SNP_fuyun/article/details/77113985?locationNum=10&fps=1

  6. 如何增强Linux和Unix服务器系统安全性

    众所周知,网络安全是一个非常重要的课题,而 Linux 和 unix 又是一种服务器上运行最广告的操作系统,下面本文将就加强一些适当的配置来防止一些安全问题的发生,以增强Linux/Unix服务器系统 ...

  7. css实现斑马线效果

    文本实现斑马线效果 <style> p { font-size: 17px; line-height: 25px; background-color: antiquewhite; back ...

  8. django基础篇06-ModelForm操作及验证

    本文内容主要来自银角大王的博客 学习大纲: 一.ModelForm 二.Ajax - 原生(jQuery) - 伪Ajax操作 三.文件上传(预览) - Form提交 - Ajax文件上传 四. 图片 ...

  9. Apache Allow 命令

    用于设置哪些客户端可以访问 Apache,格式如下: Allow from [All /全域名/部分域名/IP 地址/网络地址/CIDR 地址] All:表示全部客户端 全域名:表示域名对应的客户端, ...

  10. 03javascript01

    1.javascript语法体系 1)EMCA基础语法(统一) 2)BOM编程(不统一) 3)DOM编程(不统一) 1.1 javascript使用 <!DOCTYPE html> < ...