树形dp
_kikyou-
这个作者很懒,什么都没留下…
展开
-
Codeforces Round #279 (Div. 2) F. Treeland Tour (暴力枚举树链+LIS)
传送门给定带点权的无根树,求出所有简单路径上最长的LIS。O(N²logn)的做法:枚举每个节点作为根节点开始dfs,每条链上作一个nlogn的dp .dp[i]表示长度为i的LIS结尾的最小值当a[i]>dp[len],dp[++len] = a[i]否则二分找到a[i]可以代替的位置记得回溯的时候要恢复成原先的值。#include<bits/stdc++.h>using namespace std;//#pragma GCC optimize(2)#define原创 2021-10-13 10:25:34 · 129 阅读 · 0 评论 -
加分二叉树(区间dp+树的遍历)
题目链接思路:这题明确说明树的中序遍历是1 2 3 …n ,所以我们任取其中一段子序列,一定满足某颗子树的中序遍历 故而可以考虑用区间dp 。边界就是dp[i][i] ,另外用root[i][j]存i到j这段的根节点。有个坑点,枚举一个长度大于1的区间上的根的时候,根节点不可以出现在最右端,因为中序遍历根节点不可能出现在最末尾。...原创 2020-10-06 17:02:43 · 79 阅读 · 0 评论 -
Godfather POJ - 3107 (求树的重心)
题目链接题意:给定一棵树,要求按编号从小到大输出重心。树的重心:定义:找到一个点满足其所有的子树中最大的子树节点数最少,那么这个点就算是树的重心。性质:1.删除重心后所得的所有子树,节点数不超过原树的1/2,一棵树最多有两个重心;2.树中所有节点到重心的距离之和最小,如果有两个重心,那么他们距离之和相等;3.两个树通过一条边合并,新的重心在原树两个重心的路径上;4.树删除或添加一个叶子节点,重心最多只移动一条边;DFS求树的重心:设son[i]:以i为根的子树,孩子节点数目son[rt原创 2020-09-29 21:36:49 · 97 阅读 · 0 评论 -
[USACO12FEB]Nearby Cows G (换根dp+容斥)
思路:这题涉及距离k,k肯定要作为一个状态的。首先选一个根节点,dfs序作为有根树。我们设d[i][j] : 顶点i向下dfs, j距离内的点权和,可以直接dfs求得,dp[i][0]为边界递推过程:d[i][j]=c[i]+Σd[child][j-1]设f[i][j] : 距离顶点i ,j距离内的点权和, f[i][0] f[1][j]作为边界. 可以直接求出来递推过程是父节点->子节点 , f[child][j]=f[rt][j-1]+d[child][j]-w;其中,当j>=.原创 2020-09-28 17:01:30 · 268 阅读 · 0 评论 -
[USACO10MAR]Great Cow Gathering G (换根dp入门)
本题思路和 这题 是一样的,只不过加了边权和点权。我们需要再开一个记录点权的数组, 用sum记录点权总和换根过程:dp[child=dp[rt]+w*(sum-2*size[child]) w为rt 、child的边权,size[i]表示以i为根的树的总点权。//#pragma comment(linker, "/STACK:102400000,102400000")//手动扩栈#include<iostream>#include<algorithm>#includ.原创 2020-09-28 14:08:53 · 228 阅读 · 0 评论 -
P3478 [POI2008]STA-Station (换根dp入门)
思路:这题最朴素的想法就是,枚举根节点,每次枚举都dfs求一下其余节点的深度和。这样的话时间复杂度O(n²),绝壁tle。那该怎么优化呢?我们设dp[rt]表示以rt为根的树的所有节点的深度和。我们注意到,如果我们求出了某个dp[rt],那么对于rt的任意一个孩子节点child,dp[child]是可以通过O(1)时间求出来的。具体求法,我们在dp[rt]中是以rt为根,如果我们把根换成child,那么child所在子树的所有节点,对深度和的贡献都会减1,而除了child所在子树外的节点,贡献会加.原创 2020-09-27 21:24:50 · 252 阅读 · 0 评论 -
树上dp ——基环树 合集(持续更新ing)
最近在洛谷上写树上dp,遇到了一个叫基环树的东东。蒟蒻不自量力,也来写一篇合集 吧。什么是基环树?基环树,也是环套树,简单地讲就是树上在加一条边。它形如一个环,环上每个点都有一棵子树的形式。因此,对基环树的处理大部分就是对树处理和对环处理。显然,难度在于后者。一般来说,这种题目的做法都是先找到环,断开环中的任意一条边, 把它当成一般的树形DP来做。步骤一:找环,我们可以用dfs记录前驱,标记访问状态来找环,如果搜到某点已经访问过了,说明这个访问过的点以及其前驱必在环上。步骤二:断环,断开这条边原创 2020-09-20 00:26:24 · 733 阅读 · 0 评论 -
P2015 二叉苹果树 (树上背包入门)
题目链接题意: 给定一棵树,每条边有权重,问如果只保留e条边,最多能保留多大权重保留e条边,不容易分析,转化成保留e+1个点,权重放给孩子节点 问题转化成 保留包括根节点在内的e+1个节点,求最大权重和建树方式:链式前向星,建双边由此转化成树上01背包问题//dp[rt][m] 以rt为根,保留根节点在内的m个点的最优解,父节点的最优解由孩子节点递推而来,边界就是叶子节点 叶子->根每个孩子回溯时,对于以孩子节点为根的子树来说,只有选它和不选两种dp[rt][j]=max(dp[rt]原创 2020-09-18 12:34:29 · 119 阅读 · 0 评论 -
P1273 有线电视网 (树形背包入门)
题目链接题意:给定一棵树,叶子节点有价值,但每条边都有成本值,问在不亏本 ,也就是利益不为负数的情况下,最多能到达多少个叶子节点。 1<=n<=3000思路:这题隐约感觉不难,就是树上背包问题。 但是口胡了好久最后弄不出来,看别人的题解发现自己连状态都确定错了= =、错误想法:dp[rt][1/0]表示以rt为根的树,rt到达或不到达 且不亏本状态下 能取到的最多个 叶子节点数。 (写出来就能发现错得离谱QAQ正解:dp[rt][j]表示以rt为根的树,取j个叶子节点状态下的 最大利益值原创 2020-09-17 23:49:07 · 123 阅读 · 0 评论 -
消防局的设立 LibreOJ - 2559 (无权值的最小支配集)
题目链接无权值最小支配集:给定一棵树,树上任意点可以支配距离其不超过k的顶点,问最少选多少个点才能支配完所以的点。此题k==2.贪心,一次bfs记录好各节点深度,并用栈存好,显然这个栈是单调的,栈定元素层数最深。每次找最深层的节点,也就是栈顶元素,选择其父亲的父亲节点,并跟新标记。 细节见代码注释#include<iostream>#include<algorithm>#include<cstdio>#include<stdlib.h>#inc原创 2020-09-17 20:38:26 · 111 阅读 · 0 评论 -
P1131 [ZJOI2007]时态同步 (树上dp水题)
题目链接思路: 感觉这题是写过树上dp里面最水的一题了233dp[rt]表示以rt为根的树,修改所需最小值.具体过程看代码注释#include<iostream>#include<algorithm>#include<cstdio>#include<stdlib.h>#include<iostream>#include<algorithm>#include<cstdio>#include<std原创 2020-09-16 23:18:31 · 146 阅读 · 0 评论 -
[CQOI2009]叶子的染色 (树形dp+思维)
题目链接这题刚开始以为要枚举根,这样看数据估计得超时了。后来看了大佬的题解才发现并不需要orz。随便选一个非叶子节点作为根,确定了根我们开始dp设dp[rt][x]表示以rt为根的树 rt染成x色的最小染色点数(为什么不设立不染色的状态下面分析)首先看到题目要求,根到第i号叶子节点简单路径上最后一个染色点的颜色为c[i],由此我们可以初始化叶子节点 ,dp[y][c[y]]=1,dp[y][c[y]]=INF ,因为叶子节点就是路径的最后一个点,非c[i]色的状态就搞成INF,保证这个状态不能向原创 2020-09-16 13:05:08 · 298 阅读 · 0 评论 -
acwing 1078. 旅游规划(求树直径上的点)
题目链接题意:给一个树,可能直径不唯一,求所有直径上的所有的点思路:先用dp求直径,然后枚举每个直径中点,根据转移方程从中点dfs,把所有符合条件的点丢进set里面即可。#include<iostream>#include<algorithm>#include<cstdio>#include<stdlib.h>#include<iostream>#include<algorithm>#include<cstdio原创 2020-09-15 16:07:23 · 351 阅读 · 0 评论 -
皇宫看守 一本通 (最小支配集 树形dp)
题目链接思路:这题刚开始以为和战略游戏这题一样,但是试了发现不对劲,战略游戏是最大独立集,相连的两个点不可能同时取,但是这题是可以的。1、建图,这题需要找一下root根节点2、dp过程://dp[rt][0]:以rt为根的树中,rt不选,rt被父亲支配状态下的最优解//dp[rt][1]:以rt为根的树中,rt不选,rt被孩子支配状态下的最优解//dp[rt][2]:以rt为根的树中,rt自己选取状态下的最优解转移方程:dp[rt][0]=Σ (min (dp[child][1] , dp[原创 2020-09-14 13:16:04 · 226 阅读 · 0 评论 -
#10156. 「一本通 5.2 例 4」战略游戏(树上dp 最大独立集)
题目链接:链接题意:给定一棵树,设选取某个顶点时,和该顶点直接相连的边会被选取,问最少要选多少个点,才能把边选完。对于树上每一个点,我们有选和不选两种策略,dp[rt][1]表示以rt为根的树,选rt状态下的最优值,dp[rt][0]表示以rt为根的树,不选rt状态下的最优值。很明显,任意一个叶子节点Y,dp[Y][0]=0,dp[Y][1]=1; //边界转移方程也不难想:当根节点选的时候,孩子节点选不选都可以,取min当根节点不选的时候,孩子节点必须选dp[rt][0]=Σdp[child原创 2020-09-14 09:15:55 · 223 阅读 · 0 评论 -
一本通 数字转换 (树的直径 两种求法)
【定义】我们将一棵树T = ( V,E )的直径定义为maxδ ( u,v ) ( u,v ∈ V ),也就是说,树中所有最短路径距离的最大值即为树的直径。对于这类问题,我们主要有两种求解方法。 我们拿一个题目当例子:题目链接题意:若是一个数x的所有约数(不包括他自己)之和sum比他自己小,那么x可以转化成sum,sum也可以成 x。例如 4可以变为 3,1可以变为7限制所有数字在不超过n的正整数范围内转换,求数字变换满足无重复数字情况下的最多变换步数 。当n=7,最长为 4->3>原创 2020-09-13 21:46:13 · 222 阅读 · 0 评论 -
#10154. 「一本通 5.2 例 2」选课(树上背包入门)
题目链接题意:给定n门课程,某些课程有1门先行课,必须先修了先行课才可以选这门课,选择m门课,每门课有学分,求可以获得的最大学分数。思路:首先建树,题目给出了0号就是虚根,所以可以直接建。1、这里用链式前向星建图2、dp[rt][m]:以rt为根的树,保留m个节点状态最优解,叶子节点就是边界,叶->根,采取dfs回溯转移,dp[0][m+1]就是答案,0是虚根所以+1转移方程:dp[i][j]=max(dp[i][j],dp[child][a]+dp[i][j-a]) 枚举每个孩子 对每个原创 2020-09-12 23:56:42 · 252 阅读 · 1 评论