【Farm Craft】

【题目描述】

mhy住在一棵有n个点的树的1号结点上,每个结点上都有一个妹子。

mhy从自己家出发,去给每一个妹子都送一台电脑,每个妹子拿到电脑后就会开始安装zhx牌杀毒软件,第i个妹子安装时间为。

树上的每条边mhy能且仅能走两次,每次耗费1单位时间。mhy送完所有电脑后会回自己家里然后开始装zhx牌杀毒软件。

卸货和装电脑是不需要时间的。

求所有妹子和mhy都装好zhx牌杀毒软件的最短时间。

【Input】

第一行一个N,房屋数量

第二行N个数,C[i]

接下来的n - 1行表示相连接的房屋编号

【Output】

一个数字表示最少的时间

【Sample】

样例输入

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

样例输出

11

【Analyzation & Solution】

来看样例

模拟一下

1 3 2 3 4 5 4 6 4 3 1

此时time为10

再加上最后回到出发点的自己安装软件所需时间1

答案是11

可见,上述模拟是通过先走大的再走小的

这样的话能保证安装同时进行

那么这个贪心究竟对不对呢?

我们来看这个图

仅仅是把节点5的权值更改为了50

远远大于节点3的9

那么此时显然我们要先遍历5号节点才是最优

如果按照上述贪心一定是不成立的

那怎么办呢?

咳咳

模拟样例的过程中发现

每个节点都有两种决策

这不禁让人联想到了树型DP

定义f[i]表示遍历以i为根的子树最短所用时间

size[i]即当前子树的大小(边数)

引用某大佬の证明

假设u节点有儿子x和y,则如果先走x的话u的时间就为max(f[x]+1,f[y]+2*size[x]+1);
同理,先走 y 的话 u 的时间就为max(f[y]+1,f[x]+2*size[y]+1),若先安装x合适,则必有2*size[x]+f[y]+1>2*size[y]+f[x]+1,即f[x]-2*size[y]<f[y]-2*size[x]。
既然这样,我们排序 f[i] - size[i] 即可。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std; inline int read(){
int x = 0, w = 1;
char ch = getchar();
for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return x * w;
} const int maxn = 500000+5;
int t, c[maxn], head[maxn], n, tot;
int f[maxn], size[maxn];
int q[maxn];
struct node{
int to,nxt;
}e[maxn << 1]; inline bool cmp(int x, int y){
return f[x] - 2 * size[x] > f[y] - 2 * size[y];
} inline void add(int x, int y){
e[++tot].to = y;
e[tot].nxt = head[x];
head[x] = tot;
} inline void dfs(int u, int fa){
int cnt=0, sum=1;
if(u == 1) f[u]=0;
else f[u] = c[u];
size[u] = 1;
for(int i = head[u]; i; i = e[i].nxt){
int v = e[i].to;
if(v == fa) continue;
dfs(v,u);
size[u] += size[v];
}
for(int i = head[u]; i; i = e[i].nxt)
if(e[i].to != fa)
q[++cnt] = e[i].to;
sort(q + 1, q +1 + cnt, cmp);
for(int i = 1; i <= cnt; i++){
f[u] = max(f[u], f[q[i]] + sum);
sum += 2 * size[q[i]];
}
} int main(){
n = read();
for(int i = 1; i <= n; i++) c[i] = read();
for(int i = 1; i <= n - 1; i++){
int x = read(), y = read();
add(x, y);
add(y, x);
}
dfs(1, -1);
printf("%d", max(f[1], c[1] + 2 * (n - 1)));
return 0;
}

POI2014 FAR-FarmCraft的更多相关文章

  1. [补档][Poi2014]FarmCraft

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

  2. [BZOJ 3829][POI2014] FarmCraft

    先贴一波题面... 3829: [Poi2014]FarmCraft Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 421  Solved: 197[ ...

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

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

  4. FarmCraft[POI2014]

    题目描述 In a village called Byteville, there are   houses connected with N-1 roads. For each pair of ho ...

  5. BZOJ3829[Poi2014]FarmCraft——树形DP+贪心

    题目描述 In a village called Byteville, there are   houses connected with N-1 roads. For each pair of ho ...

  6. 【bzoj3829】[Poi2014]FarmCraft 贪心

    原文地址:http://www.cnblogs.com/GXZlegend/p/6826667.html 题目描述 In a village called Byteville, there are   ...

  7. [POI2014][树形DP]FarmCraft

    题目 In a village called Byteville, there are houses connected with N-1 roads. For each pair of houses ...

  8. BZOJ3829 : [Poi2014]FarmCraft

    d[x]表示走完x的子树并回到x所需的时间 f[x]表示从走到x开始计时,x子树中最晚的点安装完的最早时间 d[x]=sum(d[i]+2),i是x的孩子 f[x]的计算比较复杂: 考虑将x的各棵子树 ...

  9. [Poi2014]FarmCraft 树状dp

    对于每个点,处理出走完其子树所需要的时间和其子树完全下载完软件的时间 易证,对于每个点的所有子节点,一定优先选择差值大的来给后面的时间 树规+贪心. #include<cstdio> #i ...

  10. BZOJ3829 [Poi2014]FarmCraft 【树形dp】

    题目链接 BZOJ3829 题解 设\(f[i]\)为从\(i\)父亲进入\(i\)之前开始计时,\(i\)的子树中最晚装好的时间 同时记\(siz[i]\)为节点\(i\)子树大小的两倍,即为从父亲 ...

随机推荐

  1. jstat监控JVM内存使用、GC回收情况

    jstat -gcutil 2388 3000 6 每隔3秒打印一次pid为2388的堆内存的使用情况,共打印6次 S0— Heap上的 Survivor space 0 区已使用空间的百分比 S1  ...

  2. springboot实现定时任务,异步操作,统一结果返回,全局异常处理,拦截器及事务处理

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文都是springboot的常用和实用功能,话不多说开始吧 定时任务 1.启动类开启注解 @EnableScheduling //开启基于注解 ...

  3. 为什么阿里巴巴Java开发手册中强制要求接口返回值不允许使用枚举?

    在阅读<阿里巴巴Java开发手册>时,发现有一条关于二方库依赖中接口返回值不允许使用枚举类型的规约,具体内容如下: 在谈论为什么之前先来科普下什么是二方库,二方库也称作二方包,一般指公司内 ...

  4. springmvc无法进入controller,且报错404

    今天搭建一个springmvc项目时,前台一直报错404,在controller中调试发现程序没有进入controller. 通过多次刷新前台页面,发现第一次进入是会弹出错误提示,第二次之后就直接40 ...

  5. 在CentOS7上源码安装OpenResty

    您必须将这些库perl 5.6.1+libreadlinelibpcrelibssl安装在您的电脑之中. 对于 Linux来说, 您需要确认使用 ldconfig 命令,让其在您的系统环境路径中能找到 ...

  6. Ubuntu18.04下使用Hexo框架搭建个人博客

    一.安装node.js 说明:安装node.js的原因:Hexo框架是基于node.js. 1.推荐使用nvm安装速度快,也可自行百度其它方法. wget -qO- https://raw.githu ...

  7. HTML常用API(位置信息、音频视频)

    感谢:链接(讲解的很详细) 位置信息 1.代码: <script type="text/javascript"> navigator.geolocation.getCu ...

  8. Dubbo笔记(一)

    一.简介 在编写分布式场景下高并发.高扩展的系统对技能的要求很高,因为这个过程会涉及到序列化/反序列化.多线程.网络编程.设计模式.性能优化等众多专业知识.而Dubbo框架对这些专业知识做了更高层的抽 ...

  9. (八)slf4j+logback 的配置与使用

    logback的配置看这篇:https://www.cnblogs.com/lvchengda/p/13054457.html 使用 @Slf4j 1)安装插件lombok 在eclipse/myec ...

  10. python学习日记2019.9.2

    1 定义一个字符串对象str str.title() #将字符串中用空格分隔的字符段首字母大写 str.rstrip() #将字符串末的空格删去 str.strip() #将字符串首末的空格删去 st ...