树形dp学习

学习博客:https://www.cnblogs.com/qq936584671/p/10274268.html

树的性质:n个点,n-1条边,任意两个点之间只存在一条路径,可以人为设置根节点,对于任意一个节点只存在至多一个父节点,其余为子节点。

记忆化树形dp模型较为抽象难以理解,以下通过由浅到深的方式解析树形dp以及树的性质。

树形dp求树的直径:(在一颗树里找到点X,Y,使得|XY|最大)

如图,我们令A为根节点,令dfs遍历顺序为ABDGHEFC。

在我们的dfs计算过程中,我们从下往上求解每一个节点,总的来说我们要求两个东西:

1、以每一个节点为根,所能到达的最长路径dp【u】

2、以每一个节点为根,它下面的的树的最长路径ans(其实就是找到 两个没有重复路径的子树,例如以B为根节点,会找到BDG+BE而不会找到BDG+BDH)

然后将子树中以子树根为起点所能到达的最长路径传给父节点,最后得出答案

具体看下面代码:

struct Node
{
    int nex,val;
};
vector<Node>node[maxn];//node[u][i].nex代表该节点的子节点  node[u][i].val代表该节点与子节点之间路径的权值
void dfs(int u,int fa)//该节点和该节点的父亲
{
    for(int i=0;i<node[u].size();i++)
    {
        int v=node[u][i].nex;
        if(v!=fa)//防止回到父节点
        {
            dfs(v,u);//
            ans=max(ans,d[u]+d[v]+node[u][i].val);//这个必须在下面一步的前面
            d[u]=max(d[u],d[v]+node[u][i].val);
        }
    }
}

理解了基本的树形dp之后,开始下面的练习:

原文地址:https://www.cnblogs.com/caijiaming/p/10295035.html

时间: 2024-10-20 11:12:58

树形dp学习的相关文章

树形DP 学习总结

DP毕竟是算法中最精妙的部分,理解并玩得花哨还是需要一定的时间积累 之前对普通的DP也不敢说掌握,只能说略懂皮毛 在学习树形DP 的同时也算是对DP有了更深的理解吧 DP的关键就在于状态的定义以及找转移 首先要考虑清楚状态,状态要能够很好地并且完整地描述子问题 其次考虑最底层的状态,这些状态一般是最简单的情况或者是边界情况 再就是考虑某一个状态能从哪些子状态转移过来,同时还要考虑转移的顺序,确保子问题已经解决 树形DP很多时候就是通过子节点推父亲节点的状态 还是通过题目来加强理解吧 1.HDU

树形dp学习笔记

直接放例题吧: codevs1380:没有上司的舞会 题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大. 思路: 任何一个点的取舍可以看作一种决策,那么状态就是在某个点取的时候或者不取的时候,以他为根的子树能有的最大活跃总值.分别可以用f[i,1]和f[i,0]表示第i个人来和不来. 当i来的时候,dp[i][1] += dp[

poj 1655 and 3107 and 2378 树形dp(树的重心问题)

简单的树形dp,顺便学习了树的重心的概念,即以该点为根的树的最大子树的结点数最少. poj 1655: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 20001; 7 int head[N]; 8 int balance[N]; 9 int child[N]; 10 int n, e; 11 12 struct

bzoj2500: 幸福的道路(树形dp+单调队列)

好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1]+dis[x][y] up:up[fa[x]]+dis[x][y] dfs1找向下,即向子节点的最长路 dfs2找向上的最长路 最后最长路f[i]=max(up[x],g[x][0]) 第二部分 找最长连续子序列,使得序列中abs(mx-mn)<=m 这次学习了用单调队列的做法 两个队列mx,mn

青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 第一种,树形dp+LCA 比赛的时候,我猜测对于不为1的n个数,其中两两互质的对数不会很多,肯定达不到n^2 然后找出所有互质的对数,然后对为1的数进行特殊处理.(初略的估计了下,小于500的大概有50个质数,将n个数平均分到这些数中,最后大概有10000*50*200=10^7) 对所有的非1质数对,采用离

HDU 2242 连通分量缩点+树形dp

题目大意是: 所有点在一个连通图上,希望去掉一条边得到两个连通图,且两个图上所有点的权值的差最小,如果没有割边,则输出impossible 这道题需要先利用tarjan算法将在同一连通分量中的点缩成一个点后,重新构建一幅图,然后利用新建的图进行树形dp解决问题 这道题目需要注意的是可能存在重边,那么子节点回到父节点有两条边及以上的话,就需要对子节点经过父节点的边进行low值更新 tarjan算法学习的网站个人感觉还不错https://www.byvoid.com/blog/scc-tarjan/

【BZOJ-1060】时态同步 树形DP (DFS爆搜)

1060: [ZJOI2007]时态同步 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2101  Solved: 595[Submit][Status][Discuss] Description 小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数 字1,2,3….进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路板的任何两个节点,都存在且仅 存在一条通路(通路指连接两个元件的导线序列).

洛谷P2014 选课 (树形dp)

10月1日更新.题目:在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只有学完了课程a,才能学习课程b).一个学生要从这些课程里选择M门课程学习,问他能获得的最大学分是多少?输入第一行有两个整数N,M用空格隔开.(1<=N<=200,1<=M<=150)接下来的N行,第I+1行包含两个整数ki和s

树形dp入门-加分二叉树(luogu1040)

今天学习了树形dp,确实,感受到了深深的压力...一会还得去写选课那道题... 先看题目: 首先我们看到关键字:中序遍历.既然已经给出我们分数的算法,所以我们就可以通过枚举根节点来解决问题.在每一个根节点下求最优解,且记录下每一个根节点,就恰好能完成两个任务.即我们需要写两个子程序. 看代码:(请勿直接复制粘贴) #include <stdio.h> int n,point[32],f[32][32],mumber[32][32]; long long tree(int left,int ri