[POI2014]FAR-FarmCraft (树规+贪心)
题干
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.
INPUT
OUTPUT
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.
奇妙的翻译
mhy住在一棵有n个点的树的1号结点上,每个结点上都有一个妹子。
mhy从自己家出发,去给每一个妹子都送一台电脑,每个妹子拿到电脑后就会开始安装zhx牌杀毒软件,第i个妹子安装时间为。
树上的每条边mhy能且仅能走两次,每次耗费1单位时间。mhy送完所有电脑后会回自己家里然后开始装zhx牌杀毒软件。
卸货和装电脑是不需要时间的。
求所有妹子和mhy都装好zhx牌杀毒软件的最短时间。
(哪里冒出来的妹子???)
瞎想:
- 每条边都只能走两次,而且我们最后必须回到老家,意味着我们必须一次遍历完整棵树(包括每棵子树)
- 读完题我们要get到一个很重要的点:装软件和送电脑是可以同时进行的(妹子居然会装电脑! )
- 我们假设一个节点有两个子节点A和B,定义 f[i] 为遍历完子树后再回到 i 点的最短用时,siz[i] 为 i 的子树的总大小,那么,我们可以得到:
- 先去遍历A的子树,总时间:siz[A]*2 + f[B] ;//当然这里其实是要+1的,因为我们从A或B到 i 还需要再走一步,看我下面代码可以知道,这里不影响
- 先去遍历B的子树,总时间:siz[B]*2 + f[A] ;
- 我们用结构体记录下所有子树的( f[i] , siz[i]*2)
- 按照 time +p.siz < p.time + siz 从小到大排序
- 理由:如果先遍历A更合适,有 siz[A]2+f[B] < siz[B]2+f[A]; //这里之前脑子一抽写反了,希望没误导大家...
- 这里我觉得解释一下比较好,相比较而言,我们肯定更愿意先去安装软件耗时更多而跑图用时更少的子树,因为这样我们就可以让他们在我们给别的地方送电脑的时候自行安装,从而节省时间。那么在这里,我们假设f[A]和f[B]相等,那么此时siz[B]肯定是大于siz[A]的,这意味这A和B的总用时相等,但我们遍历B时耽搁在路上的时间更多(子树规模更大嘛),所以相比较而言A的装软件用时更长,也就是我们应该先走A;
- 最后的答案 f[x]=max(w[x],f[v]+sum)
这里我们结合代码分析一下:
struct node{
int time,siz;
bool operator <(const node& p)const{
return p.time+siz<time+p.siz;
}
}t[maxn];
void dfs(int u,int fa){
siz[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa) continue;
dfs(v,u);
siz[u]+=siz[v];
}
int tot=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa) continue;
tot++;//儿子数量
t[tot].time=f[v]+1;//从v回到u需加1
t[tot].siz=siz[v]*2;//这里乘2,下面计算时就不用乘2了,减少失误
}
sort(t+1,t+1+tot);
int sum=0,maxx=(siz[u]-1)*2;//sum依然是目前跑路所需总时间,maxx初始为单纯跑完u的子树所需总时间
for(int i=1;i<=tot;i++){
maxx=max(maxx,t[i].time+sum);//更新目前最大用时
sum+=t[i].siz;//累加跑路时间
}
f[u]=max(w[u],maxx);//如果单单u点装软件用时比完全弄完所有子树都费事,直接取w[u]
}
完整代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=5*1e6+10;
int n,f[maxn],head[maxn],len=0,siz[maxn];
int w[maxn];
struct Edge{
int next,to;
}edge[maxn<<1];
void Add(int u,int v){
edge[++len].next=head[u];
edge[len].to=v;
head[u]=len;
}
struct node{
int time,siz;
bool operator <(const node& p)const{
return p.time+siz<time+p.siz;
}
}t[maxn];
void dfs(int u,int fa){
siz[u]=1;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa) continue;
dfs(v,u);
siz[u]+=siz[v];
}
int tot=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fa) continue;
tot++;
t[tot].time=f[v]+1;
t[tot].siz=siz[v]*2;
}
sort(t+1,t+1+tot);
for(int i=1;i<=tot;i++)
printf("%d %d\n",t[i].time,t[i].siz);
int sum=0,maxx=(siz[u]-1)*2;
for(int i=1;i<=tot;i++){
maxx=max(maxx,t[i].time+sum);
sum+=t[i].siz;
}
f[u]=max(w[u],maxx);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=1;i<=n-1;i++){
int u,v;
scanf("%d%d",&u,&v);
Add(u,v),Add(v,u);
}
dfs(1,0);
int ans=0;
ans=max(f[1],w[1]+(n-1)*2);
cout<<ans<<endl;
return 0;
}
[POI2014]FAR-FarmCraft (树规+贪心)的更多相关文章
- [HEOI2015]兔子与樱花 树规+贪心
鬼能想到是个贪心.明明觉得是树规啊..又完美爆零.. 从叶子节点往上更新,能保证最优解(这块想了半天). 证明:当你的子树上有能删的点而你不删时,可能会对子树的根节点有利,最好的情况是使子树根节点由不 ...
- [Poi2014]FarmCraft 树状dp
对于每个点,处理出走完其子树所需要的时间和其子树完全下载完软件的时间 易证,对于每个点的所有子节点,一定优先选择差值大的来给后面的时间 树规+贪心. #include<cstdio> #i ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- BZOJ_3524_[Poi2014]Couriers_主席树
BZOJ_3524_[Poi2014]Couriers_主席树 题意:给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r- ...
- 【BZOJ5495】[十二省联考2019]异或粽子(主席树,贪心)
[BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如 ...
- 【arc073e】Ball Coloring(线段树,贪心)
[arc073e]Ball Coloring(线段树,贪心) 题面 AtCoder 洛谷 题解 大型翻车现场,菊队完美压中男神的模拟题 首先钦定全局最小值为红色,剩下的袋子按照其中较大值排序. 枚举前 ...
- 【9.2校内测试】【开学祭】【exgcd】【树规(背包】【模拟】
比较裸的$exgcd$的应用? $exgcd$可以算出在$x$和$y$分别是最小正整数时的解.注意在这里因为有$a(x+\frac{b}{d})+b(y-\frac{a}{d})=c$,$d=gcd( ...
- 【agc028E】High Elements(动态规划,线段树,贪心)
[agc028E]High Elements(动态规划,线段树,贪心) 题面 AtCoder 你有一个\([1,N]\)的排列\(P\). 一个长度为\(N\)的字符串\(S\)是好的,当且仅当: 两 ...
- BZOJ3829[Poi2014]FarmCraft——树形DP+贪心
题目描述 In a village called Byteville, there are houses connected with N-1 roads. For each pair of ho ...
随机推荐
- lambda操作DataTable进阶版
using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Text; ...
- 容器技术之Dockerfile(三)
前面我们聊到了dockerfile的 FROM.COPY .ADD.LABAL.MAINTAINER.ENV.ARG.WORKDIR.VOLUME.EXPOSE.RUN.CMD.ENTRYPOINT指 ...
- N47-冯天驰-学习进度计划表
马哥就业课程学习进度规划--N47-冯天驰 第一周 6.1-6.7 8. 06- ...
- Koa源码解析,带你实现一个迷你版的Koa
前言 本文是我在阅读 Koa 源码后,并实现迷你版 Koa 的过程.如果你使用过 Koa 但不知道内部的原理,我想这篇文章应该能够帮助到你,实现一个迷你版的 Koa 不会很难. 本文会循序渐进的解析内 ...
- ODEINT 求解常微分方程(4)
import numpy as np from scipy.integrate import odeint import matplotlib.pyplot as plt # function tha ...
- phpstorm 安装 YUI Compressor 实 结合现自动压缩文件
YUI compressor 官方: http://yui.github.io/yuicompressor/ 下载的快速入口: https://github.com/yui/yuicompressor ...
- 【Vulnhub】FristiLeaks v1.3
靶机信息 下载连接 https://download.vulnhub.com/fristileaks/FristiLeaks_1.3.ova.torrent https://download.vuln ...
- Dart Memo for Android Developers
Dart Memo for Android Developers Dart语言一些语法特点和编程规范. 本文适合: 日常使用Kotlin, 突然想写个Flutter程序的Android程序员. Dar ...
- 色彩空间转换 rgb转ycbcr422/ycbcr422转rgb
在图像处理过程中通常需要会对图像类型进行互相转换,在此给出两种转换的工程代码. 1.在将ycbCr422转rgb时,通常先将ycbcr422转换成ycbcr444再讲ycbcr444转成rgb 1.1 ...
- vulstack红队评估(二)
一.环境搭建: 1.根据作者公开的靶机信息整理: 靶场统一登录密码:1qaz@WSX 2.网络环境配置: ①Win2008双网卡模拟内外网: 外网:192.168.1.80,桥接模式与物理机相 ...