树形DP水题系列(1):FAR-FarmCraft [POI2014][luogu P3574]
大意:
边权为1 使遍历树时到每个节点的时间加上点权的最大值最小 求这个最小的最大值
思路:
最优化问题 一眼树形DP
考虑状态设立 先直接以答案为状态 dp[u] 为遍历完以u为根的子树的答案
再考虑状态转移 dp[u]=MAX(dp[to]+1,siz+dp[to]);siz为枚举子树到以to为节点的子树时之前已遍历的总时间
很明显这个转移过来的dp值的最优化依赖于子树遍历的顺序 所以我们需要找到一种最优的子树遍历顺序来使每个子树得到最优的dp值来更新
我们通过观察可以发现 交换任意两个相邻的子树在遍历时的顺序不会对它们之前的子树和之后的子树造成影响 所以我们考虑贪心 如果只有两个子树 a和b 遍历完子树a,b的时间分别为 siz[a],siz[b],dp值分别为dp[a],dp[b];
将 a优先遍历得到的dp值为MAX(dp[a]+1,siz[a]+dp[b]+3);
将 b优先遍历得到的dp值为MAX(dp[b]+1,siz[b]+dp[a]+3);
注意到取MAX时有一个值不被顺序影响 故只需要将后面的值最优化即可
我们假设a更优 则 siz[a]+dp[b]+3<siz[b]+dp[a]+3即siz[a]-dp[a]<siz[b]-dp[b]
将子树排序后转移即可
时间复杂度粗略估计(nlogn)
代码如下
#include <cstdio>
#include <iostream>
#include <algorithm>
#define MAXX 500005
#define MAX(a,b) (a>b?a:b)
#define r(x) x=read()
using namespace std;
typedef long long ll;
int h[MAXX],cnt,u,to;
int top,n;
ll dp[MAXX],w[MAXX],siz[MAXX];
struct node{ ll a,b;}nod[MAXX];
struct edge{int to,nex;}e[MAXX<<];
void add(int u,int to)
{
cnt++;
e[cnt]=(edge){to,h[u]};
h[u]=cnt;
}
bool cmp(node a,node b){return a.b-a.a<b.b-b.a;}
void dfs(int now,int fa)
{
if(now!=) {dp[now]=w[now];}
for(int i=h[now];i;i=e[i].nex)
{
if(e[i].to==fa) continue;
dfs(e[i].to,now);
}
for(int i=h[now];i;i=e[i].nex)
{
if(e[i].to==fa) continue;
nod[++top]=(node){dp[e[i].to],siz[e[i].to]};
}
sort(nod+,nod+top+,cmp);
for(int i=;i<=top;++i)
{
dp[now]=MAX(dp[now],siz[now]++nod[i].a);
siz[now]+=nod[i].b+;
}
if(now==) dp[now]=MAX(dp[now],siz[now]+w[now]);
top=;
}
ll read()
{
ll w=,ff=;char ch=;
while(ch<''||ch>''){if(ch=='-')ff=-;ch=getchar();}
while(ch>=''&&ch<=''){w=w*+ch-'';ch=getchar();}
return w*ff;
}
int main()
{
r(n);
for(int i=;i<=n;++i)
r(w[i]);
for(int i=;i<n;++i)
r(u),r(to),add(u,to),add(to,u);
dfs(,);
printf("%lld",dp[]);
return ;
}
树形DP水题系列(1):FAR-FarmCraft [POI2014][luogu P3574]的更多相关文章
- POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题
一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...
- 树形DP水题杂记
BZOJ1131: [POI2008]Sta 题意:给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大. 题解:记录每个点的深度,再根据根节点的深度和逐层推导出其他点的深度和. ...
- nyoj 1208——水题系列——————【dp】
水题系列 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 给你一个有向图,每条边都有一定的权值,现在让你从图中的任意一点出发,每次走的边的权值必须必上一次的权 ...
- ACM :漫漫上学路 -DP -水题
CSU 1772 漫漫上学路 Time Limit: 1000MS Memory Limit: 131072KB 64bit IO Format: %lld & %llu Submit ...
- [poj2247] Humble Numbers (DP水题)
DP 水题 Description A number whose only prime factors are 2,3,5 or 7 is called a humble number. The se ...
- POJ 1155 TELE 背包型树形DP 经典题
由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送 ...
- POJ 2342 树形DP入门题
有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...
- Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题
除非特别忙,我接下来会尽可能翻译我做的每道CF题的题面! Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题 题面 胡小兔和司公子都认为对方是垃圾. 为了决出谁才是垃 ...
- 51nod 1353 树 | 树形DP经典题!
51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...
随机推荐
- IE大文件断点续传
IE的自带下载功能中没有断点续传功能,要实现断点续传功能,需要用到HTTP协议中鲜为人知的几个响应头和请求头. 一. 两个必要响应头Accept-Ranges.ETag 客户端每次提交下载请求时,服务 ...
- luoguP1034 矩形覆盖 x
P1034 矩形覆盖 题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4( ...
- Springboot(九).多文件上传下载文件(并将url存入数据库表中)
一. 文件上传 这里我们使用request.getSession().getServletContext().getRealPath("/static")的方式来设置文件的存储 ...
- Centos6.6 安装Mysql集群
一.环境准备 1.1系统IP设置 准备三台服务器安装Centos6.6 64位操作系统,IP地址及角色分配如下: Node IP Address ...
- [CSP-S模拟测试]:字符交换(贪心+模拟)
题目传送门(内部题136) 输入格式 输入文件第一行为两个正整数$n,k$,第二行为一个长度为$n$的小写字母字符串$s$. 输出格式 输出一个整数,为对字符串$s$进行至多$k$次交换相邻字符的操作 ...
- [CSP-S模拟测试]:统计(树状数组+乱搞)
题目传送门(内部题120) 输入格式 第一行,两个正整数$n,m$. 第二行,$n$个正整数$a_1,a_2,...,a_n$,保证$1\leqslant a_i\leqslant n$,可能存在相同 ...
- vue跳转到指定位置
document.querySelector(id).scrollIntoView(true)//跳转到顶部 window.scrollTo(0, 0)
- JPA查询getOne()与findOne()的差异以及一些小问题
起初用Jpa 里面 getOne() 查询一个id的数据 发现查询出来的数据都是空的,但不是空的对象是按照对象默认值来的 所以导致查询不出结果 以为是数据库修改,没有及时修改实体类导致的 但是后来发现 ...
- String、toString、String.valueOf()三个有啥区别?
今天在使用这个的时候发现,他们三者好像在某些场所都是可以用的,但是不免会让人想到那既然它们三者这么的相似,那么总有些什么区别吧.我也在网上找了一些资料看.自己也看了API文档,就将他们三的区别总结一下 ...
- ThreadPool用法与优势
1. 线程池的优点: 合理利用线程池能够带来三个好处.第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗.第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执 ...