https://codeforces.com/contest/1084/problem/D?tdsourcetag=s_pctim_aiomsg
题意:一个树,点有值,边有值,求任意两点之间的最大值,遇到点要加它对应的值,遇到边减掉它对应的值。
思路:嗯,题意理解做法水的一笔,任意两点的路径的最大值,可以采用dfs,回溯到父亲结点,与它两个较大的(可能一个或零个)子节点的路径构成最大路径。
#include<bits/stdc++.h> using namespace std; #define ll long long const int maxn=6e5+10; ll f[maxn]; int val[maxn]; int head[maxn],nxt[maxn],ver[maxn]; ll edge[maxn]; int tot=0; void add(int u,int v,ll w) { ver[++tot]=v; edge[tot]=w; nxt[tot]=head[u]; head[u]=tot; } ll ans=0; void dfs(int u,int fa) { ll maxx1=0; ll maxx2=0; for(int i=head[u]; i; i=nxt[i]) { int v=ver[i]; ll w=edge[i]; if(v==fa) continue; dfs(v,u); if((f[v]+w)>=maxx1) { maxx2=maxx1; maxx1=f[v]+w; } else if((f[v]+w)>maxx2) maxx2=f[v]+w; } ans=max(ans,maxx1+maxx2+val[u]); f[u]=val[u]+maxx1; } int main() { int n; scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&val[i]); for(int i=1; i<=n-1; i++) { int u,v; ll w; scanf("%d%d%lld",&u,&v,&w); add(u,v,-w); add(v,u,-w); } dfs(1,0); printf("%lld",ans); }
原文地址:https://www.cnblogs.com/dongdong25800/p/11071919.html
时间: 2024-10-11 06:55:52