• 2020Nowcode多校 Round9 B.Groundhog and Apple Tree


    题意

    给一棵树 初始(hp=0) 经过一条边会掉血(w_{i}) 第一次到达一个点可以回血(a_{i}) 在一个点休息(1s)可以回复(1hp) 血不能小于(0)
    每条边最多经过两次 求从起点经过所有点再回到起点到最小时间

    题解

    休息的话干脆就在起点休息够了再出发吧
    在分叉路口的时候走哪个方向是个问题
    对于每一棵子树 可以维护出走这个方向的最小(hp) 和走回来还剩下的(hp)
    那么可以根据这两个值的大小关系把子树分成两种 一种是走回来回的血比走之前掉的血还多 还有一种...
    显然可以在第一种的选一个掉血最少的开始先走 走完之后还剩一些血
    对于剩下的 比较一下谁先走更优

    #include <bits/stdc++.h>
    #include <stdio.h>
    #include <iostream>
    #include <set>
    #include <string.h>
    #include <string>
    #include <map>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int mod = 998244353;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 100005;
    
    int n, cnt;
    int a[MAXN];
    struct node {
        int to, nex, val;
    }E[MAXN << 1];
    int head[MAXN];
    
    struct ed {
        int id;
        ll cost, gain;
    }dp[MAXN];
    
    bool cmp(ed A, ed B) {
        if(A.gain > A.cost) {
            if(B.gain > B.cost) return A.cost < B.cost;
            else return true;
        } else {
            if(B.gain > B.cost) return false;
            else return A.gain > B.gain;
        }
    }
    
    void dfs(int x, int fa) {
        vector<ed> comp;
        for(int i = head[x]; i; i = E[i].nex) {
            int v = E[i].to;
            if(v == fa) continue;
            
            dfs(v, x);
            dp[v].id = v;
            dp[v].cost += E[i].val; 
            dp[v].gain -= E[i].val;
            if(dp[v].gain < 0) dp[v].cost -= dp[v].gain, dp[v].gain = 0;
    
            comp.push_back(dp[v]);
        }
        sort(comp.begin(), comp.end(), cmp);
    
        dp[x].cost = 0;
        ll now = a[x];
        for(int i = 0; i < comp.size(); i++) {
        
            ed v = comp[i];
            now -= v.cost;
            if(now < 0) {
                dp[x].cost += -now;
                now = 0;
            }
            now += v.gain;
        }
        dp[x].gain = now;
    }
    
    int main() {
        int T;
        cin>>T;
        while(T--) {
            cnt = 0;
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) scanf("%d", &a[i]), head[i] = 0;
    
            for(int i = 1; i < n; i++) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                E[++cnt].to = v; E[cnt].nex = head[u]; head[u] = cnt; E[cnt].val = w;
                E[++cnt].to = u; E[cnt].nex = head[v]; head[v] = cnt; E[cnt].val = w;
            }
            dfs(1, 0);
            printf("%lld
    ", dp[1].cost);
        }
        return 0;
    }
    
    
  • 相关阅读:
    Pycharm破解
    Web UI绕过登录的实现
    使用Docker安装Jenkins服务
    Appium 基于控件左滑操作
    Pytest执行用例报Hint: make sure your test modules/packages have valid Python names.
    Selenium文件上传
    获取Android手机日志
    Linux机器间ssh免密登录
    JMeter中使用Put请求方式请求接口
    python发送post请求上传文件,无法解析上传的文件
  • 原文地址:https://www.cnblogs.com/lwqq3/p/13461278.html
Copyright © 2020-2023  润新知