题目描述

In a village called Byteville, there are   houses connected with N-1 roads. For each pair of houses, there is a unique way to get from one to another. The houses are numbered from 1 to  . The house no. 1 belongs to the village administrator Byteasar. As part of enabling modern technologies for rural areas framework,   computers have been delivered to Byteasar's house. Every house is to be supplied with a computer, and it is Byteasar's task to distribute them. The citizens of Byteville have already agreed to play the most recent version of FarmCraft (the game) as soon as they have their computers.
Byteasar has loaded all the computers on his pickup truck and is about to set out to deliver the goods. He has just the right amount of gasoline to drive each road twice. In each house, Byteasar leaves one computer, and immediately continues on his route. In each house, as soon as house dwellers get their computer, they turn it on and install FarmCraft. The time it takes to install and set up the game very much depends on one's tech savviness, which is fortunately known for each household. After he delivers all the computers, Byteasar will come back to his house and install the game on his computer. The travel time along each road linking two houses is exactly 1 minute, and (due to citizens' eagerness to play) the time to unload a computer is negligible.
Help Byteasar in determining a delivery order that allows all Byteville's citizens (including Byteasar) to start playing together as soon as possible. In other words, find an order that minimizes the time when everyone has FarmCraft installed.
mhy住在一棵有n个点的树的1号结点上,每个结点上都有一个妹子。
mhy从自己家出发,去给每一个妹子都送一台电脑,每个妹子拿到电脑后就会开始安装zhx牌杀毒软件,第i个妹子安装时间为Ci。
树上的每条边mhy能且仅能走两次,每次耗费1单位时间。mhy送完所有电脑后会回自己家里然后开始装zhx牌杀毒软件。
卸货和装电脑是不需要时间的。
求所有妹子和mhy都装好zhx牌杀毒软件的最短时间。

输入

The first line of the standard input contains a single integer N(2<=N<=5 00 000)  that gives the number of houses in Byteville. The second line contains N integers C1,C2…Cn(1<=Ci<=10^9), separated by single spaces; Ci is the installation time (in minutes) for the dwellers of house no. i.
The next N-1  lines specify the roads linking the houses. Each such line contains two positive integers a and b(1<=a<b<=N) , separated by a single space. These indicate that there is a direct road between the houses no. a and b.

输出

The first and only line of the standard output should contain a single integer: the (minimum) number of minutes after which all citizens will be able to play FarmCraft together.

样例输入

6
1 8 9 6 3 2
1 3
2 3
3 4
4 5
4 6

样例输出

11

提示

Explanation: Byteasar should deliver the computers to the houses in the following order: 3, 2, 4, 5, 6, and 1. The game will be installed after 11, 10, 10, 10, 8, and 9 minutes respectively, in the house number order. Thus everyone can play after 11 minutes.
If Byteasar delivered the game in the following order: 3, 4, 5, 6, 2, and 1, then the game would be installed after: 11, 16, 10, 8, 6, and 7 minutes respectively. Hence, everyone could play only after 16 minutes,
 
首先能想到一定是按什么顺序来遍历子树的,遍历一棵子树一定要遍历完才遍历其他子树,那么按什么顺序遍历呢?
不妨设f[i]表示以i为根节点的子树中最长耗时是多少(是指从i开始走的最长耗时)。
对于一个点i的两个子节点a,b(其中size[]代表子树大小):
如果先遍历a再遍历b,则a的耗时是1+f[a],b的耗时是1+2*size[a]+f[b]
如果先遍历b再遍历a,则a的耗时是1+2*size[b]+f[a],b的耗时是1+f[b]
f[i]=min(max(f[a],2*size[a]+f[b]),max(f[b],2*size[b]+f[a]))
到这一步就可以按上式排序遍历了,但还可以再进一步简化。
我们分类讨论上式两个最大值分别是什么:
1、f[a]>2*size[a]+f[b];f[b]>2*size[b]+f[a],这种情况显然是不可能的
2、f[a]>2*size[a]+f[b];2*size[b]+f[a]>f[b],显然2*size[b]+f[a]>f[a]>2*size[a]+f[b],这种情况优先遍历a更优
即2*size[b]+f[a]>2*size[a]+f[b],f[a]-2*size[a]>f[b]-2*size[b],也就是优先遍历f[]-2*size[]大的
3、2*size[a]+f[b]>f[a];f[b]>2*size[b]+f[a],显然2*size[a]+f[b]>f[b]>2*size[b]+f[a],这种情况优先遍历b更优
即2*size[a]+f[b]>2*size[b]+f[a],f[b]-2*size[b]>f[a]-2*size[a],同样是优先遍历f[]-2*size[]大的
4、2*size[a]+f[b]>f[a];2*size[b]+f[a]>f[b],假设遍历a更优,反过来同样
即2*size[a]+f[b]<2*size[b]+f[a],f[b]-2*size[b]<f[a]-2*size[a],依然是优先遍历f[]-2*size[]大的
那么只要按f[]-2*size[]排序之后更新f[i]就好了。
因为1号节点要求回来再安装,因此将f[1]初始成0,最后再比较一下f[1]和2*size[1]-2+c[1]的大小即可。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int c[500010];
int n;
int head[500010];
int to[1000010];
int next[1000010];
int size[500010];
int fa[500010];
ll f[500010];
int q[500010];
int x,y;
int tot;
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
bool cmp(int x,int y)
{
return f[x]-2*size[x]>f[y]-2*size[y];
}
void dfs(int x)
{
int cnt=0;
int sum=1;
size[x]=1;
f[x]=c[x];
if(x==1)
{
f[x]=0;
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=fa[x])
{
fa[to[i]]=x;
dfs(to[i]);
size[x]+=size[to[i]];
}
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=fa[x])
{
q[++cnt]=to[i];
}
}
sort(q+1,q+1+cnt,cmp);
for(int i=1;i<=cnt;i++)
{
f[x]=max(f[x],f[q[i]]+sum);
sum+=2*size[q[i]];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
}
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1);
printf("%lld",max(2ll*(n-1)+c[1],f[1]));
}

BZOJ3829[Poi2014]FarmCraft——树形DP+贪心的更多相关文章

  1. bzoj 3829: [Poi2014]FarmCraft 树形dp+贪心

    题意: $mhy$ 住在一棵有 $n$ 个点的树的 $1$ 号结点上,每个结点上都有一个妹子. $mhy$ 从自己家出发,去给每一个妹子都送一台电脑,每个妹子拿到电脑后就会开始安装 $zhx$ 牌杀毒 ...

  2. 【BZOJ3829】[Poi2014]FarmCraft 树形DP(贪心)

    [BZOJ3829][Poi2014]FarmCraft Description In a village called Byteville, there are   houses connected ...

  3. [POI2014]FAR-FarmCraft 树形DP + 贪心思想

    (感觉洛谷上题面那一小段中文根本看不懂啊,好多条件都没讲,直接就是安装也要一个时间啊,,,明明不止啊!还好有百度翻译......) 题意:一棵树,一开始在1号节点(root),边权都为1,每个点有点权 ...

  4. POI2014 FAR-FarmCraft 树形DP+贪心

    题目链接 https://www.luogu.org/problem/P3574 题意 翻译其实已经很明确了 分析 这题一眼就是贪心啊,但贪心的方法要思索一下,首先是考虑先走时间多的子树,但不太现实, ...

  5. [bzoj3829][Poi2014]FarmCraft_树形dp

    FarmCraft 题目链接:https://lydsy.com/JudgeOnline/problem.php?id=3829 数据范围:略. 题解: 因为每条边只能必须走两次,所以我们的路径一定是 ...

  6. 【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心

    题目描述 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它 ...

  7. 【BZOJ3522】[Poi2014]Hotel 树形DP

    [BZOJ3522][Poi2014]Hotel Description 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房 ...

  8. [BZOJ1596] [Usaco2008 Jan]电话网络(树形DP || 贪心)

    传送门 1.树形DP #include <cstdio> #include <cstring> #include <iostream> #define N 1000 ...

  9. BZOJ3522[Poi2014]Hotel——树形DP

    题目描述 有一个树形结构的宾馆,n个房间,n-1条无向边,每条边的长度相同,任意两个房间可以相互到达.吉丽要给他的三个妹子各开(一个)房(间).三个妹子住的房间要互不相同(否则要打起来了),为了让吉丽 ...

随机推荐

  1. xrange 和range的区别

    >>> xrange(5)xrange(5)>>> list(xrange(5))[0, 1, 2, 3, 4]>>> xrange(1,5)xr ...

  2. SkylineGlobe 如何二次开发实现天际线分析功能

    天际线效果: 示例代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <h ...

  3. WPF-利用Blend写的平面控制闸门开关动画

    原文:WPF-利用Blend写的平面控制闸门开关动画 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/de ...

  4. 将WinForm程序(含多个非托管Dll)合并成一个exe的方法

    原文:将WinForm程序(含多个非托管Dll)合并成一个exe的方法 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. ILMerge能把托管dl ...

  5. [Spark][Python]sortByKey 例子

    [Spark][Python]sortByKey 例子: [training@localhost ~]$ hdfs dfs -cat test02.txt00002 sku01000001 sku93 ...

  6. [Oracle]ORA-600[kdBlkCheckError]LOB坏块处理

    [Oracle]ORA-600[kdBlkCheckError]LOB坏块处理 客户环境报如下错误: ORA - 00600: Internal error code, arguments: [kdB ...

  7. 扫描shader

    游戏中经常需要制作出白光扫描的效果,这道光在透明区域不会显示.如果用图片叠加可能透明区域不太好处理,这里可通过shader实现. Shader "Custom/LogoShader" ...

  8. 线程池(ThreadPool)

    线程池概述 由系统维护的容纳线程的容器,由CLR控制的所有AppDomain共享.线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器. 线程池与线程 性能:每开启一个新 ...

  9. 编写自己的dapper lambda扩展-使用篇

    前言 这是针对dapper的一个扩展,支持lambda表达式的写法,链式风格让开发者使用起来更加优雅.直观.现在暂时只有MsSql的扩展,也没有实现事务的写法,将会在后续的版本补充. 这是个人业余的开 ...

  10. 大数据之Flume

    什么是Flume ApacheFlume是一个分布式的.可靠的.可用的系统,用于高效地收集.聚合和将大量来自不同来源的日志数据移动到一个集中的数据存储区. 系统要求 1. JDK 1.8 或以上版本 ...