• Codeforces Round #526 D


    题目大意:

    给定一棵树 树上每个点有对应的点权

    树上每条边有对应的边权

    经过一个点可得到点权 经过一条边必须花费边权

    即从u到v 最终得分=u的点权-u到v的边权+v的点权

    求树上一条路径使得得分最大

    看注释

    #include <bits/stdc++.h>
    #define LL long long
    #define INf 0x3f3f3f3f
    using namespace std;
    const int N=3e5+5;
    bool vis[N];
    LL w[N], ans;
    int n;
    struct NODE { int to,nt; LL l; }e[N<<1];
    int head[N], tot;
    void addE(int u,int v,LL l) {
        e[tot].to=v, e[tot].l=l;
        e[tot].nt=head[u];
        head[u]=tot++;
    }
    void init() {
        memset(head,0,sizeof(head));
        tot=1;
    }
    LL dfs(int u,int fa) {
        vis[u]=1;
        LL ans1=0LL, ans2=0LL; 
        // ans1由子节点出发的一条路径最大得分 ans2为次大
        for(int i=head[u];i;i=e[i].nt) {
            int v=e[i].to;
            if(v==fa || vis[v]) continue;
            LL tmp=dfs(v,u)-e[i].l;
            if(tmp>ans1) swap(tmp,ans1); 
            if(tmp>ans2) swap(tmp,ans2);
        }
        ans=max(ans,ans1+ans2+w[u]);
        // 可由最大得分和次大得分加上u点 得到一条经过u点的路径的最大得分
        return ans1+w[u]; // 只返回由u出发的一条路径可得到的最大得分
    }
    int main()
    {
        while(~scanf("%d",&n)) {
            for(int i=1;i<=n;i++) scanf("%I64d",&w[i]);
            init();
            for(int i=1;i<n;i++) {
                int u,v; LL l;
                scanf("%d%d%I64d",&u,&v,&l);
                addE(u,v,l); addE(v,u,l);
            }
            memset(vis,0,sizeof(vis));
            ans=0LL;
            dfs(1,0);
            printf("%I64d
    ",ans);
        }
    
        return 0;
    }
  • 相关阅读:
    Munge
    file upload custom form
    随笔摘要
    生成css 和 清缓存
    drupal commit 原则
    Git reset --hard
    www-data
    301/302的区别
    什么是request_uri
    in_array foreach array_search的性能比较
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10104350.html
Copyright © 2020-2023  润新知