bzoj3829 [Poi2014]FarmCraft

http://www.elijahqi.win/2018/02/22/bzoj3829-poi2014farmcraft/
Description

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牌杀毒软件的最短时间。
Input

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.
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.
Sample Input

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

11
HINT

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
因为考虑到1我最后才能走到 所以先将他的c改成0 放到最后考虑 那么设f[x]表示x子树中最后一个软件被安装完是什么时候 那么考虑x的两个子树 a,b
如果先访问a 那么a的答案就是f[a]+1,b的答案是size[a]*2+f[b]+1
先访问b a的答案是size[b]*2+f[a]+1 b的答案是f[b]+1
若先安装a合适,则必有2*size[a]+f[b]+1>2*size[b]+f[a]+1,即f[a]-2*siize[a]< f[b]-2*size[b]
所以我在做每个子树的时候贪心针对所有子树sort的时候这样排序 然后选择一下即可

#include<cstdio>
#include<algorithm>
#define N 550000
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
    return x*f;
}
struct node{
    int y,next;
}data[N<<1];
struct node1{
    int f,size;
}tree[N],q[N];
int num,h[N],c[N],n;
inline void insert1(int x,int y){
    data[++num].y=y;data[num].next=h[x];h[x]=num;
    data[++num].y=x;data[num].next=h[y];h[y]=num;
}
inline bool cmp(const node1 &a,const node1 &b){
    return a.size*2-a.f<b.size*2-b.f;
}
inline void dfs(int x,int fa){
    tree[x].f=c[x];tree[x].size=1;int now=1,cnt=0;
    for (int i=h[x];i;i=data[i].next) {
        int y=data[i].y;if (y==fa) continue;dfs(y,x);tree[x].size+=tree[y].size;
    }
    for (int i=h[x];i;i=data[i].next){
        int y=data[i].y;if (y==fa) continue;q[++cnt]=tree[y];
    }sort(q+1,q+cnt+1,cmp);
    for (int i=1;i<=cnt;++i) tree[x].f=max(tree[x].f,now+q[i].f),now+=q[i].size<<1;
}
int main(){
    freopen("bzoj3829.in","r",stdin);
    n=read();for (int i=1;i<=n;++i) c[i]=read();int tmp=c[1];c[1]=0;
    for (int i=1;i<n;++i){
        int x=read(),y=read();
        insert1(x,y);
    }dfs(1,0);printf("%d",max(tree[1].f,(n-1<<1)+tmp));
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值