题目描述

Alice和Bob有一棵树(无根、无向),在第i个点上有ai个巧克力。首先,两人个选择一个起点(不同的),获得点上的巧克力;接着两人轮流操作(Alice先),操作的定义是:在树上找一个两人都没选过的点并获得点上的巧克力,并且这个点要与自己上一次选的点相邻。当有一人无法操作 时,另一个人可以继续操作,直到不能操作为止。因为Alice和Bob是好朋友,所以他们希望两人得到的巧克力总和尽量大,请输出最大总和。

数据范围

对于20%的数据,n<=15

对于40%的数据,n<=100

对于60%的数据,n<=5000

对于100%的数据,n<=200000,0<=ai<=1000000000(1e9)

=w=

题目模型显然:寻找一棵树上的两条不相交的链使得权值和最大。

树形动态规划。

分两种情况讨论:

1.两条链靠近(存在一条树边,两个端点分居这两条链中);

2.两条链分居一个结点的两颗子树。

易推。

代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;
const char* fin="aP2.in";
const char* fout="aP2.out";
const ll inf=0x7fffffff;
const ll maxn=200007,maxm=maxn*2;
ll n,i,j,k,maxx,mxid,ans;
ll a[maxn],fi[maxn],la[maxm],ne[maxm],tot;
ll f[maxn],g[maxn],st[maxn],pre[maxn],spre[maxn],suf[maxn],ssuf[maxn];
ll Pre[maxn],Suf[maxn];
ll h[maxn],h1[maxn];
bool ban[maxn],ok[maxn];
void add_line(ll a,ll b){
tot++;
ne[tot]=fi[a];
la[tot]=b;
fi[a]=tot;
}
void xdfs(ll v,ll from){
ll i,j,k,maxx,smaxx,tmp;
st[0]=0;
for (k=fi[v];k;k=ne[k]) if (la[k]!=from) st[++st[0]]=g[la[k]];
if (from) st[++st[0]]=h1[v];
maxx=smaxx=0;
for (i=1;i<=st[0];i++){
if (maxx<st[i]){
smaxx=maxx;
maxx=st[i];
}else smaxx=max(st[i],smaxx);
pre[i]=maxx;
spre[i]=smaxx;
}
suf[st[0]+1]=ssuf[st[0]+1]=0;
maxx=smaxx=0;
for (i=st[0];i;i--){
if (maxx<st[i]){
smaxx=maxx;
maxx=st[i];
}else smaxx=max(st[i],smaxx);
suf[i]=maxx;
ssuf[i]=smaxx;
}
tmp=0;
for (k=fi[v];k;k=ne[k]) if (la[k]!=from) {
tmp++;
i=max(pre[tmp-1],suf[tmp+1]);
j=max(min(pre[tmp-1],suf[tmp+1]),max(spre[tmp-1],ssuf[tmp+1]));
h1[la[k]]=i+a[v];
h[la[k]]=a[v]+i+j;
}
for (k=fi[v];k;k=ne[k]) if (la[k]!=from) xdfs(la[k],v);
ans=max(ans,h[v]+f[v]);
}
void dfs(ll v,ll from){
ll i,j,k,maxx,smaxx,tmp;
g[v]=a[v];
for (k=fi[v];k;k=ne[k]){
if (la[k]!=from){
dfs(la[k],v);
g[v]=max(g[v],g[la[k]]+a[v]);
f[v]=max(f[v],f[la[k]]);
}
}
st[0]=0;
for (k=fi[v];k;k=ne[k]) if (la[k]!=from) st[++st[0]]=la[k];
maxx=smaxx=0;
for (i=1;i<=st[0];i++){
if (maxx<g[st[i]]){
smaxx=maxx;
maxx=g[st[i]];
}else smaxx=max(g[st[i]],smaxx);
pre[i]=maxx;
spre[i]=smaxx;
Pre[i]=max(Pre[i-1],f[st[i]]);
}
Suf[st[0]+1]=suf[st[0]+1]=ssuf[st[0]+1]=0;
maxx=smaxx=0;
for (i=st[0];i;i--){
if (maxx<g[st[i]]){
smaxx=maxx;
maxx=g[st[i]];
}else smaxx=max(g[st[i]],smaxx);
suf[i]=maxx;
ssuf[i]=smaxx;
Suf[i]=max(Suf[i+1],f[st[i]]);
}
f[v]=max(f[v],maxx+smaxx+a[v]);
tmp=0;
for (k=fi[v];k;k=ne[k])
if (la[k]!=from){
tmp++;
i=max(pre[tmp-1],suf[tmp+1]);
j=max(min(pre[tmp-1],suf[tmp+1]),max(spre[tmp-1],ssuf[tmp+1]));
ans=max(ans,f[la[k]]+i+j+a[v]);
ans=max(ans,f[la[k]]+max(Pre[tmp-1],Suf[tmp+1]));
}
}
int main(){
scanf("%lld",&n);
for (i=1;i<=n;i++) scanf("%lld",&a[i]);
for (i=1;i<n;i++){
scanf("%lld%lld",&j,&k);
add_line(j,k);
add_line(k,j);
}
dfs(1,0);
xdfs(1,0);
printf("%lld",ans);
return 0;
}

=o=

求最大值和次大值,可以维护三大边。

不用像我维护什么前缀最大值,和后缀最大值= =

【JZOJ4923】【NOIP2017提高组模拟12.17】巧克力狂欢的更多相关文章

  1. 求hack or 证明(【JZOJ 4923】 【NOIP2017提高组模拟12.17】巧克力狂欢)

    前言 本人在此题有一种不是题解的方法,但无法证明也找不到反例. 如果各位大神有反例或证明请发至 邮箱:qq1350742779@163.com Description Alice和Bob有一棵树(无根 ...

  2. 【NOIP2017提高组模拟12.17】环

    题目 小A有一个环,环上有n个正整数.他有特殊的能力,能将环切成k段,每段包含一个或者多个数字.对于一个切分方案,小A将以如下方式计算优美程度: 首先对于每一段,求出他们的数字和.然后对于每段的和,求 ...

  3. 【JZOJ4922】【NOIP2017提高组模拟12.17】环

    题目描述 小A有一个环,环上有n个正整数.他有特殊的能力,能将环切成k段,每段包含一个或者多个数字.对于一个切分方案,小A将以如下方式计算优美程度: 首先对于每一段,求出他们的数字和.然后对于每段的和 ...

  4. 【JZOJ4924】【NOIP2017提高组模拟12.17】向再见说再见

    题目描述 数据范围 =w= 设h[i]表示,甲队得到i分的方案数. 那么h[(n+k)/2]和h[(n−k)/2]就是答案. 设g[i]表示,甲队得到至少i分的方案数. 那么h[i]=g[i]−∑j& ...

  5. 【NOIP2017提高组模拟12.24】B

    题目 现在你有N个数,分别为A1,A2,-,AN,现在有M组询问需要你回答.每个询问将会给你一个L和R(L<=R),保证Max{Ai}-Min{Ai}<=R-L,你需要找出并输出最小的K( ...

  6. 【NOIP2017提高组模拟12.10】幻魔皇

    题目 幻魔皇拉比艾尔很喜欢斐波那契树,他想找到神奇的节点对. 所谓斐波那契树,根是一个白色节点,每个白色节点都有一个黑色节点儿子,而每个黑色节点则有一个白色和一个黑色节点儿子.神奇的节点对则是指白色节 ...

  7. 【NOIP2017提高组模拟12.10】神炎皇

    题目 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对(a,b),若满足a+b<=n且a+b是ab的因子,则成为神奇的数对.请问这样的数对共有多少呢? 分析 设\(gcd(a,b)= ...

  8. 【JZOJ4930】【NOIP2017提高组模拟12.18】C

    题目描述 给出一个H的行和W列的网格.第i行第j列的状态是由一个字母的A[i][j]表示,如下: "." 此格为空. "o" 此格包含一个机器人. " ...

  9. 【JZOJ4929】【NOIP2017提高组模拟12.18】B

    题目描述 在两个n*m的网格上染色,每个网格中被染色的格子必须是一个四联通块(没有任何格子被染色也可以),四联通块是指所有染了色的格子可以通过网格的边联通,现在给出哪些格子在两个网格上都被染色了,保证 ...

随机推荐

  1. vue v-for详解

    1.Vue动态渲染列表------v-for用法详解: Html: <figure v-for="list in lists">     <div>     ...

  2. 留下来做项目经理还是跳槽学Java

    毕业两年了,曾经给自己计划工作两年后跳一次槽,去尝试学习更多的东西.2012年7月5日入职,现在整整两年,最近面临这样的一个抉择:是留在公司继续做项目经理,还是跳槽去学习Java. 我的基本情况:本科 ...

  3. java填坑记录

    一.The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in either web.xml or the ...

  4. MyBatis映射器(一)--多参数传递方式

    在mybatis映射器的接口中,一般在查询时需要传递一些参数作为查询条件,有时候是一个,有时候是多个.当只有一个参数时,我们只要在sql中使用接口中的参数名称即可,但是如果是多个呢,就不能直接用参数名 ...

  5. 一个班六个人,学号语文、数学、英语,接收成绩(不接受学号),输出学号成绩,总分、平均分,按总分排序(原生JS)

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  6. PAT甲级——A1051 Pop Sequence

    Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, ..., N and p ...

  7. Eureka Instance实例信息配置

    Eureka包含四个部分的配置 instance:当前Eureka Instance实例信息配置 client:Eureka Client客户端特性配置 server:Eureka Server注册中 ...

  8. PetaPoco 基础操作

    //初始化数据库连接 var db=new PetaPoco.Database("connectionStringName"); //查询单个值 long count=db.Exe ...

  9. bzoj 1029 [JSOI2007]建筑抢修——贪心(伪dp)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1029 当然要按结束时间排序,然后按顺序修或跳过.就是那种“……不会使答案不优”的证明. 想了 ...

  10. AntColony 磁力搜索引擎的核心

    介绍 AntColony(Github)是findit磁力搜索引擎的核心.用来在DHT网络中,收集活跃资源的infohash,下载并解析资源的种子文件,存入数据库等.AntColony是若干功能的合集 ...