zoukankan      html  css  js  c++  java
  • Groundhog and Apple Tree【贪心】-2020牛客暑期多校9

    题意

    给一棵树,初始 (hp=0) 经过一条边会掉血 (w_i),第一次到达一个点可以回血 (a_i) 在一个点休息 (1 s)可以回复 (1 hp) ,除此之外其他操作不消耗时间,血不能小于 (0)。每条边最多经过两次,求从起点经过所有点再回到起点到最小时间。

    题目链接:https://ac.nowcoder.com/acm/contest/5674/B

    分析

    关键在于如何规划子树的访问顺序来优化问题的解。

    在根节点恢复够了 (HP) 一定更优,

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<int,int>pii;
    const int N=1e5+5;
    int a[N];
    struct node
    {
        int id;
        ll cost,gain;
        bool operator < (const node b)const
        {
            if(gain>cost)
            {
                if(b.gain>b.cost) return cost<b.cost;
                else return true;
            }
            else
            {
                if(b.gain>b.cost) return false;
                else return gain>b.gain;
            }
        }
    }dp[N];
    vector<pii> pic[N];
    void dfs(int u,int p)
    {
        vector<node>point;
        for(int i=0;i<pic[u].size();i++)
        {
            pii tmp=pic[u][i];
            if(tmp.second==p) continue;
            dfs(tmp.second,u);
            dp[tmp.second].id=tmp.second;
            dp[tmp.second].cost+=tmp.first;
            dp[tmp.second].gain-=tmp.first;
            if(dp[tmp.second].gain<0)
            {
                dp[tmp.second].cost+=(-dp[tmp.second].gain);
                dp[tmp.second].gain=0;
            }
            point.pb(dp[tmp.second]);
        }
        sort(point.begin(),point.end());//排序确定子树的访问顺序
        ll now=a[u];
        dp[u].cost=0;
        for(int i=0;i<point.size();i++)
        {
            node tmp=point[i];
            now-=tmp.cost;
            if(now<0)
            {
                dp[u].cost+=(-now);
                now=0;
            }
            now+=tmp.gain;
        }
        dp[u].gain=now;
    }
    int main()
    {
        int T,n;
        scanf("%d",&T);
        while(T--)
        {
            int u,v,w;
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                pic[i].clear();
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                pic[u].pb(make_pair(w,v));
                pic[v].pb(make_pair(w,u));
            }
            dfs(1,0);
            printf("%lld
    ",dp[1].cost);
        }
        return 0;
    }
    
    

    参考博客:https://www.cnblogs.com/lwqq3/p/13461278.html

  • 相关阅读:
    为什么你的Excel很丑?
    老白聊数据-为什么你的营销总是没有效?
    零售企业需要什么技术和策略
    老白聊数据-关于销售预测的那些事
    在大数据时期的营销该是什么样子的
    基于数据驱动的活动该如何设计
    DAU新解
    小白学数据分析----->DNU/DAU
    [db]db学习笔记(目录)
    [net]网络工程学习笔记(目录)
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13495074.html
Copyright © 2011-2022 走看看