树形DP入门专题

目录

一、简单树形DP

  1、 Anniversary party

  2、Godfather

  3、树上子链

  特点

二、子树计数

  4、 codeforces 767C Garland

  5、 洛谷1122最大子树和

  6、距离和

  特点

三、树形背包

    6、 洛谷1272重建道路

  7、 洛谷1273有线电视网

  特点

四、种类数

  8、51Nod - 1588 幸运树

  9、CodeForces - 161D 

  特点

五、其他

  11、HDU - 2196 


一、简单树形DP

  1、Anniversary party

接:Anniversary party

题意:给一个有点权的树,选取的点不能有相邻的,求最大权

思路:

       很经典的入门题,直接根据题意DP

分别得出该点选和不选的最好结果即可。

  2、Godfather

链接Godfather

题意:求树的重心的点

思路:

        就是求树的重心,有个简单版本的题小G有一个大树,可以双for去dfs遍历出结果,但是有点拉了

这题多组输入,stl建树基本卡死,树形DP一个点的下面最大子树值dp[i][1],以及包含自己的最大子树值dp[i][0]。

最后结果就是max(dp[i][1],n-dp[i][0])。

  3、树上子链 

链接树上子链

题意:求树的直径的长度

思路:

        求树的直径,虽然点权有负值,但树的直径性质仍然可用,但是dfs两遍求就有点la

        树DP求出每个点以下最长的链,更新过该点的最长链,maxx=max(maxx,dp[顶]+dp[子])

        以上只是大概,还有些细节最好自己想

特点

        根据题意直接进行DP,一般统计的是最大或最优,没有特别的模板和思维,和普通DP很像

二、子树计数

  4、codeforces 767C Garland

链接:codeforces 767C Garland

题意:给一颗树,每个点有点权(可为负),删除两个边后的三个树的点权和相等。

思路:

        大概就是将一些很不确定的题意,转化为确定的做法,偏向于思维。

        任何一个子树结点数为sum/3都一定可以在该点断

题解:Garland

  5、洛谷1122最大子树和

链接:洛谷1122最大子树和

题意:给一个有点权的树,求找出一片联通的顶点的权值和最大

思路:

        一个比较经典的树形DP问题,回溯更新

        下点只要是>0就要,<0的话为0也就是不要。

  6、距离和

链接:距离和

题意:求每个顶点到其他点的距离

思路:

        先求出子树结点数,和第1个节点的答案,根据点移动的答案变化规律,从上往下推出其他点的答案。

详细题解:#224. 距离和

特点

        偏向于思维,需要想明白整个题的思路,很多细节都 是绝对的,直接看别人题解码几乎没有意义

三、树形背包

    6、洛谷1272重建道路

链接:洛谷1272重建道路

思路:

        DP[i][j]表示i点分出j个结点,最少需要的次数,回溯更新得出答案。

  7、洛谷1273有线电视网

链接:洛谷1273有线电视网

思路:

        和上题很像,DP[i][j]表示i点连接j个用户,得到最多的资金

        用差不多的模板进行更新,比较特殊的就是一个子节点数的优化

  特点

        一个点不再是一两个状态,而是m个状态,核心在于顶点和子点的m个状态更新

        而代码也似乎有所固定,做多一点仿佛就没有那么难了

四、种类数

  8、51Nod - 1588 幸运树

链接:51Nod - 1588 幸运树

思路:给一个有边权的树,边权有4,7是幸运边,找经过幸运边的三元组。

思路:

        贡献思维,先看一个点,求的是一个点能走到两个点,而且不能走到点是联通着的,这个用dfs标记搜索求

        而n-不能走到的就是可以走到的,从中选取两个的种类数*2就是答案

题解:51nod1588幸运树

  9、CodeForces - 161D

链接:CodeForces - 161D 

题意:找出树中两点距离<=k的对数

思路:

        这题如果给了较大的边权,需要按这题做:poj1741

        个人觉得很不错的一道题,更新和答案是两种,就是DP[i][j]表示的是i点以下j距离的有多少点,而统计答案+=顶点的DP选 h 和子点DP选 m-h+1,因为这两个点连接的话长度会+1

        for(int h=0;h<m;h++) sum+=dp[d][h]*dp[son][m-h-1];
        for(int j=m;j>=1;j--) dp[d][j]+=dp[son][j-1];

特点

        这类题应该是比较多的,特别是牛客周赛经常出这类题,思路大多应该是单点贡献,DP,转化为数学计算等。

五、其他

  11、HDU - 2196

链接:HDU - 2196 

题意:求每个点距离某个点最远的距离

思路:

        这题是利用数的直径的性质,一般的DP的值一直都是从小到大的,而这题每个点的答案都是一个比较大的值。所以要么多个DP求最大或计算,要么利用性质(这题是利用树的直径的性质)。

猜你喜欢

转载自blog.csdn.net/m0_58177653/article/details/123991383
今日推荐