#pragma GCC optimize(3, "Ofast", "inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod=998244353;
const int maxn=1e5+10;
LL w[maxn];
vector<int> G[maxn];
int n;
LL f[maxn][2];
LL g[maxn],h[maxn],down[maxn];
/*f[u][0] 表示以u为根的子树中最长的两条链之和
f[u][1] 表示以u为根的子树中最长的一条链
g[u] 表示以u为根的子树中从u到叶子节点加上另外一条链的最长长度*
h[u] 表示以u为根的子树中儿子节点中f[son][1]的最大值*
down[u] 表示从u到叶子节点的最长长度*/
void dfs(int u,int fa)
{
f[u][0]=w[u];
f[u][1]=w[u];
g[u]=w[u];
h[u]=0;
down[u]=w[u];
int len=G[u].size();
for(int i=0;i<len;i++){
int to=G[u][i];
if(to==fa)continue;
dfs(to,u);
f[u][0]=max(f[u][0],f[to][0]);
f[u][0]=max(f[u][0],f[u][1]+f[to][1]);
f[u][0]=max(f[u][0],down[u]+g[to]);
f[u][0]=max(f[u][0],g[u]+down[to]);
f[u][1]=max(f[u][1],f[to][1]);
f[u][1]=max(f[u][1],down[u]+down[to]);
g[u]=max(g[u],w[u]+g[to]);
g[u]=max(g[u],down[u]+f[to][1]);
g[u]=max(g[u],w[u]+down[to]+h[u]);
h[u]=max(h[u],f[to][1]);
down[u]=max(down[u],down[to]+w[u]);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&w[i]);
}
for(int i=1;i<=n-1;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);G[v].push_back(u);
}
dfs(1,0);
printf("%lld\n",f[1][0]);
return 0;
}
The Chocolate Spree CodeForces - 633F(树形dp求树中两条不相交路径上点权和最大值)
最新推荐文章于 2022-11-25 18:22:00 发布