• AcWing 3760. 最大剩余油量(树的最长路径)


    题目

    一个国家由 n 个城市组成,这 n 个城市由 n−1 条双向道路连接,呈一个树形结构。

    每个城市都设有加油站,在第 i 个城市可以购买 wi 升汽油。

    汽车在道路上行驶,毫无疑问也会消耗汽油,每条道路的具体耗油量也会给出。

    现在,需要制定一条汽车的行进路线,从任意城市 s 出发,经过一条简单路径,到达任意城市 e 结束。

    注意,行进路线也可以只包含一个城市(也就是哪都没去)。

    汽车初始时油箱是空的,但是可以在路线中经过的每个城市购买汽油,包括开始城市和最终城市。

    如果在一条行进路线中,汽车沿一条道路从某一城市开往另一城市时,现有油量小于该条道路所需油量,那么就说明这条行进路线行不通。

    请问,在保证行进路线合理的情况下,汽车在抵达最终城市后,可以剩余的最大油量是多少?

    再次提醒,汽车在最终城市也可以加油。

    输入输出

    输入:第一行包含整数 n。

    第二行包含 n 个整数 w1,w2,…,wn。

    接下来 n−1 行,每行包含三个整数 u,v,c,表示城市 u 和城市 v 之间存在一条双向道路,耗油量为 c。
    输出:一个整数,表示可能的最大剩余油量。

    思路

    这道题是选出一条路径使最大剩余油量最大,即树的最长路径(树的直径)问题。点权为正,边权为负。
    可以枚举一条路径的最高点,该点的最长路径由根节点的点权+子树的最长长度+子树的次长长度。用递归来做,递归返回的是子树往下的最长长度,计算出后,更新最长路径长度。写的太混乱了

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 300010;
    typedef long long LL;
    
    int tot;
    int head[N << 1],ver[N << 1], nxt[N << 1],edge[N << 1];
    int w[N];
    LL ans;
    void add(int u, int v, int c)  // 添加一条边a->b
    {
        ver[++tot] = v; nxt[tot] = head[u]; head[u] = tot; edge[tot] = c;
    }
    
    LL dfs(int u,int fa){
        LL max1=0,max2=0;   //以u为根节点的子树中最大的长度和次大的长度
        for(int i = head[u];i;i = nxt[i]){
            int v = ver[i];
            if(v == fa) continue;
            LL d = dfs(v,u);    //d是以v为根节点的子树的最长路径
            if(d < edge[i]) continue;
            d -= edge[i];  //走子树到根节点需要耗费油量
            if(d >= max1) max2 = max1,max1 = d; //先更新max2,再更新max1
            else if(d > max2) max2 = d;
        }
        ans = max(ans, max1 + max2 + w[u]);
        return max1 + w[u]; //返回的是以u为根节点的最长路径
    }
    
    int main()
    {
        int n;
        cin >> n;
        for (int i = 1; i <= n; i ++ )  cin >> w[i];
        for (int i = 0; i < n-1; i ++ ){
            int u,v,c;
            cin >> u >> v >> c;
            add(u, v, c);
            add(v, u, c);
        }
        dfs(1,0);
        cout << ans;
    }
    
    
    作者:inss!w!
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 相关阅读:
    android debug:stack trace
    android binder IPC 通信中 asInterface 与 asBinder
    ubuntu WPS 对话框 使用GTK主题的方法
    init.rc
    make_ext4fs 文件权限控制
    百度地图api,点击标注,改变标注marker图标的链接地址
    dispatchEvent 自定义触发事件,常用于自定义鼠标事件或点击事件
    vue 中监听窗口发生变化,触发监听事件, window.onresize && window.addEventListener('resize',fn) ,window.onresize无效的处理方式
    chomre 控制台断点调试
    css,scss解决样式:表格的重叠边框
  • 原文地址:https://www.cnblogs.com/Hfolsvh/p/15025542.html
Copyright © 2020-2023  润新知