CF1083A The Fair Nut and the Best Path

CF1083A The Fair Nut and the Best Path

  • 先把边权搞成点权(其实也可以不用),那么就是询问树上路径的最大权值.
  • 任意时刻权值非负的限制可以不用管,因为若走路径 \(u\to v\) ,走到 \(w\) 权值为负数了,那么直接从 \(w\) 下一个点开始走显然更优.这个限制是多余的.
  • 那么问题就很简单了,经典 \(dp\) 做法,记 \(f(i)\)\(i\) 子树内一点到 \(i\) 所有路径中的最大权值, \(O(n)\) 即可解决问题.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
    int x=0;
    bool pos=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            pos=0;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return pos?x:-x;
}
const int MAXN=6e5+10;
int cnt,head[MAXN],to[MAXN<<1],nx[MAXN<<1];
int w[MAXN];
inline void addedge(int u,int v)
{
    ++cnt;
    to[cnt]=v;
    nx[cnt]=head[u];
    head[u]=cnt;
    swap(u,v);
    ++cnt;
    to[cnt]=v;
    nx[cnt]=head[u];
    head[u]=cnt;
}
int n;
ll f[MAXN];
ll ans=0;
void upd(ll x,ll &mx,ll &sc)
{
    if(x>=mx)
        sc=mx,mx=x;
    else if(x>sc)
        sc=x;
}
void dfs(int u,int fa)
{
    ll mx=0,sc=0;
    for(int i=head[u];i;i=nx[i])
        {
            int v=to[i];
            if(v==fa)
                continue;
            dfs(v,u);
            upd(f[v],mx,sc);
        }
    f[u]=mx+w[u];
    ans=max(mx+sc+w[u],ans);
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i)
        w[i]=read();
    for(int i=1;i<n;++i)
        {
            int u=read(),v=read();
            addedge(u,i+n);
            addedge(v,i+n);
            w[i+n]=-1*read();
        }
    dfs(1,0);
    cout<<ans<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/jklover/p/10418077.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值