树形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=;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之后,开始下面的练习:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4616
学习链接:https://www.cnblogs.com/zyb993963526/p/7223861.html
题目大意:在一颗有n(n<5e4)个节点的树中,每个节点有权值和是否有陷阱,你可以最多踏进c(c<=3)个陷阱,当你进入第c个陷阱时,你就无法继续移动了,你可以在任意节点出发,获取经过节点的权值(无法重复获取同一个节点),求能得到的最大权值和。
思路:
有点像树链剖分,对于一个以u为根的子树,因为每个顶点只能经过一次,那我们只能选择它的一个子树往下走。就像是把这棵树分成许多链,最后再连接起来。
这道题目麻烦的地方是陷阱的处理,用d【u】【j】【0/1】表示以u为根的某一子节点经过j个陷阱后到达u的最大权值和,0/1表示起点是否有陷阱。
假设当前到达u时经过了k个陷阱,分下面几种情况进行讨论:
①如果k==c,那么起点和终点至少有一个是陷阱(可能有些人会认为终点一定会是陷阱,这样是没错的,因为起点和终点时相对的,你也可以把起点看做终点)。
②如果k<c,那么起点和终点是否是陷阱是任意的,可以有也可以没有。
具体看代码:
#include<iostream>
#include<vector>
#include<math.h>
#include<string.h>
using namespace std;
const int maxn=+;
int n,c;
int ans;
vector<int>G[maxn];
int val[maxn],trap[maxn];//分别存储节点的值和是否有陷阱
int d[maxn][][];//d[u][j][0/1]表示以u为根的某一子节点经过j个陷阱之后到达u的最大权值和
void dfs(int u,int fa)
{
d[u][trap[u]][trap[u]]=val[u]; //计算以u为根的子树所能获得的最大值,也就是将子树的链进行连接
for(int i=;i<G[u].size();i++)
{
int v=G[u][i];
if(v!=fa)
{
dfs(v,u);
for(int j=;j<=c;j++)
{
for(int k=;j+k<=c;k++)
{
if(j!=c) ans=max(ans,d[u][j][]+d[v][k][]);
if(k!=c) ans=max(ans,d[u][j][]+d[v][k][]);
if(j+k<c) ans=max(ans,d[u][j][]+d[v][k][]);//起点和终点都可以为非陷阱
if(j+k<=c) ans=max(ans,d[u][j][]+d[v][k][]);//起点和终点都可以为陷阱 }
}
for(int j=;j+trap[u]<=c;j++)
{
d[u][j+trap[u]][]=max(d[u][j+trap[u]][],d[v][j][]+val[u]);
if(j!=)
{
d[u][j+trap[u]][]=max(d[u][j+trap[u]][],d[v][j][]+val[u]);
}
}
}
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>c;//n个节点 最多可以踩c个陷阱
for(int i=;i<n;i++) G[i].clear();
for(int i=;i<n;i++) cin>>val[i]>>trap[i];//输入值和是否有陷阱
for(int i=;i<n;i++)
{
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
ans=;
memset(d,,sizeof(d));
dfs(,-);
cout<<ans<<endl;
}
}
树形dp学习的更多相关文章
- 树形DP 学习笔记
树形DP学习笔记 ps: 本文内容与蓝书一致 树的重心 概念: 一颗树中的一个节点其最大子树的节点树最小 解法:对与每个节点求他儿子的\(size\) ,上方子树的节点个数为\(n-size_u\) ...
- 树形$dp$学习笔记
今天学习了树形\(dp\),一开始浏览各大\(blog\),发现都\(TM\)是题,连个入门的\(blog\)都没有,体验极差.所以我立志要写一篇可以让初学树形\(dp\)的童鞋快速入门. 树形\(d ...
- 树形DP学习笔记
树形DP 入门模板题 poj P2342 大意就是一群职员之间有上下级关系,每个职员有一个快乐值,但是只有在他的直接上级不在场的情况下才会快乐.求举行一场聚会的快乐值之和的最大值. 求解 声明一个数组 ...
- 树形DP 学习笔记(树形DP、树的直径、树的重心)
前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶 ...
- 树形dp|无根树转有根树|2015年蓝桥杯生命之树
2015年蓝桥杯第十题--生命之树(无根树dfs) ①暴力解法:枚举子集(选点) + dfs判断连通性(题目要求连通)满足上面两个条件下找出最大值权值和 ②dfs无根树转有根树,递归找最优 先学习无根 ...
- 树形DP入门学习
这里是学习韦神的6道入门树形dp进行入门,本来应放在day12&&13里,但感觉这个应该单独放出来好点. 这里大部分题目都是参考的韦神的思想. A - Anniversary part ...
- [学习笔记]树形dp
最近几天学了一下树形\(dp\) 其实早就学过了 来提高一下打开树形\(dp\)的姿势. 1.没有上司的晚会 我的人生第一道树形\(dp\),其实就是两种情况: \(dp[i][1]\)表示第i个人来 ...
- bzoj2500: 幸福的道路(树形dp+单调队列)
好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...
- 【BZOJ-1060】时态同步 树形DP (DFS爆搜)
1060: [ZJOI2007]时态同步 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2101 Solved: 595[Submit][Statu ...
随机推荐
- Entity Framework Tutorial Basics(4):Setup Entity Framework Environment
Setup Entity Framework Environment: Entity Framework 5.0 API was distributed in two places, in NuGet ...
- Entity Framework Code-First(23):Entity Framework Power Tools
Entity Framework Power Tools: Entity Framework Power Tools (currently in beta 3) has been released. ...
- .replace(/-/g,"/")的用法
/-/g正则表达式 g 代表 global 全部替换 var str1 ="2012-08-12 23:13"; str1 = str1.replace(/-/g,& ...
- cs231n knn
# coding: utf-8 # In[19]: import random import numpy as np from cs231n.data_utils import load_CIFAR1 ...
- [转]Marshaling a SAFEARRAY of Managed Structures by P/Invoke Part 4.
1. Introduction. 1.1 In parts 1 through 3 of this series of articles, I have thoroughly discussed th ...
- JavsScript中JSON相关
1.JSON.parse(jsonString) JSON.parse(jsonString):将一个JSON格式的字符串字面值,转换成JSON对象,它的逆运算方法是JSON.stringify(ob ...
- code manager tools myeclipse10 svn插件安装及使用
一.下载: 1.在线安装地址:http://subclipse.tigris.org/update_1.6.x 2.安装包下载地址:http://subclipse.tigris.org/servle ...
- Win10下Tensorflow+GPU的环境配置
不得不说,想要为深度学习提前打好框架确实需要花费一番功夫.本文主要记录了Win10下,Cuda9.0.Cudnn7.3.1.Tensorflow-gpu1.13.1.python3.6.8.Keras ...
- Percona5.6源码安装
---恢复内容开始--- 系统环境:CentOS 6.8 1.安装依赖包 yum install gcc-c++ make cmake bison bison-devel ncurses-devel ...
- P4012 深海机器人问题
\(\color{#0066ff}{题目描述}\) 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人 ...