D. The Fair Nut and the Best Path

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