题干

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 (树规+贪心)的更多相关文章

  1. [HEOI2015]兔子与樱花 树规+贪心

    鬼能想到是个贪心.明明觉得是树规啊..又完美爆零.. 从叶子节点往上更新,能保证最优解(这块想了半天). 证明:当你的子树上有能删的点而你不删时,可能会对子树的根节点有利,最好的情况是使子树根节点由不 ...

  2. [Poi2014]FarmCraft 树状dp

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

  3. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  4. BZOJ_3524_[Poi2014]Couriers_主席树

    BZOJ_3524_[Poi2014]Couriers_主席树 题意:给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r- ...

  5. 【BZOJ5495】[十二省联考2019]异或粽子(主席树,贪心)

    [BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如 ...

  6. 【arc073e】Ball Coloring(线段树,贪心)

    [arc073e]Ball Coloring(线段树,贪心) 题面 AtCoder 洛谷 题解 大型翻车现场,菊队完美压中男神的模拟题 首先钦定全局最小值为红色,剩下的袋子按照其中较大值排序. 枚举前 ...

  7. 【9.2校内测试】【开学祭】【exgcd】【树规(背包】【模拟】

    比较裸的$exgcd$的应用? $exgcd$可以算出在$x$和$y$分别是最小正整数时的解.注意在这里因为有$a(x+\frac{b}{d})+b(y-\frac{a}{d})=c$,$d=gcd( ...

  8. 【agc028E】High Elements(动态规划,线段树,贪心)

    [agc028E]High Elements(动态规划,线段树,贪心) 题面 AtCoder 你有一个\([1,N]\)的排列\(P\). 一个长度为\(N\)的字符串\(S\)是好的,当且仅当: 两 ...

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

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

随机推荐

  1. Jmeter连接数据库进行参数化

    实际使用Jmeter进行性能测试或接口测试自动化过程中,很多场景需要从数据库中获取一些关键性参数,或进行一些断言,比较,那么如何进行数据库连接以及怎么获取参数就变得尤为重要 一.下载mysql驱动 1 ...

  2. Django如何上传图片并对上传图片进行访问

    通过一个示例的完整演示过程,来学习django如何上传图片,以及对于media文件夹中的上传图片进行请求: 1.配置settings.py MEDIA_URL = '/media/' MEDIA_RO ...

  3. linux下gdb调试方法与技巧整理

    参考博客:  https://blog.csdn.net/niyaozuozuihao/article/details/91802994 1.运行命令run:简记为 r ,其作用是运行程序,当遇到断点 ...

  4. Jmeter(八) - 从入门到精通 - JMeter配置元件(详解教程)

    1.简介 JMeter配置元件可以用来初始化默认值和变量,读取文件数据,设置公共请求参数,赋予变量值等,以便后续采样器使用.将在其作用域的初始化阶段处理.配置元件(Config Element)提供对 ...

  5. EIGRP-10-弥散更新算法-计算距离,报告距离,可行距离和可行性条件

    对于某个目的网络,EIGRP持续关注它的各种距离参数.EIGRP使用复合度量参数,不过为了简化,这里使用一个没有单位的数值.同样出于简化,这里的EIGRP路由器都不使用水平分割.

  6. pycharm安装破解方法

    1.pycharm专业版官方下载链接:http://www.jetbrains.com/pycharm/download/#section=windows正常下载并安装 2.从https://gith ...

  7. fiddler修改请求参数

    1.打开fiddler ,点击界面左侧左侧底部 2.此图标为before request请求(修改请求参数时,设置这个,可以修改请求参数) 3..再次点击该按钮,将图标切换到下图after respo ...

  8. Netty中的这些知识点,你需要知道!

    一.Channel Channel是一个接口,而且是一个很大的接口,我们称之为“大而全”,囊括了server端及client端接口所需要的接口. Channel是一个门面,封装了包括网络I/O及相关的 ...

  9. gatewayworker 安装 pcntl 扩展

    安装其它扩展也是如此. 第一步,查看php版本: /phpstudy/server/php/bin/php -v 第二步,下载扩展文件: http://php.net/releases/  这里面寻找 ...

  10. 观察者模式(Observer Pattern)(二):HeadFirst中的气象站的实现

    1 观察者模式的原理,首先由一个主题,当主题发送变化的时候,通知该主题的订阅者 按照上面的分析我们来进行设计 1.抽象主题Subject public interface Subject { publ ...