这个题的状态还是比较好设的。。

设d[i][j]为以i为根,有j个路径且还有根到叶子的半链的最大值

c[i][j]为以i为根,有j个路径的最大值

然后感觉是可以转移了,不过写的时候转移发现十分麻烦。。需要正确的姿势

将子树逐步合并,然后维护d和c,转移的时候需要另开一个g(为以i为根,有j个不经过i的路径的最大值)来辅助转移。。

然后都是细节问题了。。怎么转移见代码。。

 

/**
*         ┏┓    ┏┓
*         ┏┛┗━━━━━━━┛┗━━━┓
*         ┃       ┃  
*         ┃   ━    ┃
*         ┃ >   < ┃
*         ┃       ┃
*         ┃... ⌒ ...  ┃
*         ┃ ┃
*         ┗━┓ ┏━┛
*          ┃ ┃ Code is far away from bug with the animal protecting          
*          ┃ ┃ 神兽保佑,代码无bug
*          ┃ ┃           
*          ┃ ┃       
*          ┃ ┃
*          ┃ ┃           
*          ┃ ┗━━━┓
*          ┃ ┣┓
*          ┃ ┏┛
*          ┗┓┓┏━━━━━━━━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-12
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 400005
#define nm 800005
#define N 1000005
#define M(x,y) x=max(x,y)
const double pi=acos(-1);
const ll inf=998244353;
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}


struct edge{int t;edge*next;}e[nm],*h[NM],*o=e;
void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}

int n,_x,_y,a[NM],f[NM];
ll _g[5],_d[5],_c[5],d[NM][5],c[NM][5],g[NM][5];

void dfs(int x){
d[x][0]=a[x];
c[x][1]=a[x];
link(x)if(j->t!=f[x]){
f[j->t]=x;
dfs(j->t);
mem(_c);mem(_d);mem(_g);
inc(i,0,2)inc(k,1,i)_d[i]=max(_d[i],c[j->t][k]+d[x][i-k]);
inc(i,0,2)inc(k,0,i-1)_d[i]=max(_d[i],d[j->t][k]+a[x]+g[x][i-k]);
inc(i,0,2)_d[i]=max(_d[i],d[j->t][i]+a[x]);
inc(i,1,3)_c[i]=max(_c[i],c[j->t][i]);
inc(i,1,3)_g[i]=max(_g[i],c[j->t][i]);
inc(i,1,3)inc(k,1,i-1)_c[i]=max(_c[i],c[j->t][k]+c[x][i-k]);
inc(i,1,3)inc(k,1,i-1)_g[i]=max(_g[i],c[j->t][k]+g[x][i-k]);
inc(i,1,3)inc(k,0,i-1)_c[i]=max(_c[i],d[j->t][k]+d[x][i-1-k]);
inc(i,1,3)c[x][i]=max(c[x][i],_c[i]);inc(i,0,2)d[x][i]=max(d[x][i],_d[i]);
inc(i,1,3)g[x][i]=max(g[x][i],_g[i]);
}
}

int main(){
n=read();
inc(i,1,n)a[i]=read();
inc(i,1,n-1){_x=read();_y=read();add(_x,_y);add(_y,_x);}
dfs(1);
return 0*printf("%lld\n",c[1][3]);
}

 

链接:​​https://www.nowcoder.com/acm/contest/140/H​​​
travel

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

White Cloud has a tree with n nodes.The root is a node with number 1. Each node has a value.
White Rabbit wants to travel in the tree 3 times. In Each travel it will go through a path in the tree.
White Rabbit can't pass a node more than one time during the 3 travels. It wants to know the maximum sum value of all nodes it passes through.

 

 

输入描述:


The first line of input contains an integer n(3 <= n <= 400001) In the next line there are n integers in range [0,1000000] denoting the value of each node. For the next n-1 lines, each line contains two integers denoting the edge of this tree.


输出描述:


Print one integer denoting the answer.


示例1

输入

复制


13 10 10 10 10 10 1 10 10 10 1 10 10 10 1 2 2 3 3 4 4 5 2 6 6 7 7 8 7 9 6 10 10 11 11 12 11 13


输出

复制


110