nowcoder多校2H(树形DP)

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

设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

猜你喜欢

转载自blog.csdn.net/qkoqhh/article/details/81151069