• [CF1399E1] Weights Division


    [CF1399E1] Weights Division - 贪心,堆

    Description

    给定一棵以 1 为根的带权树,一条路径的权值为边的权值之和,你可以进行一系列的操作,操作零次或多次。对于每次操作,你可以选择任意一条边,将其权值除以 2,找到最小操作数,以满足所有从根到叶子的路径的权值之和不超过 S。

    Solution

    因为要求的是和,所以可以贪心处理

    预处理每条边出现次数,所有边扔到堆中,每次取最大的 (w-w/2)c,其中 c 为出现次数,然后再扔回堆中

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int n, s;
    vector<pair<int, int>> g[N];
    int w[N], siz[N];
    
    void dfs1(int p, int from)
    {
        siz[p] = 0;
        for (auto [q, wei] : g[p])
            if (q != from)
            {
                w[q] = wei;
                dfs1(q, p);
                siz[p] += siz[q];
            }
        siz[p] = max(siz[p], 1ll);
    }
    
    void solve()
    {
        cin >> n >> s;
        for (int i = 1; i <= n; i++)
            g[i].clear(), w[i] = siz[i] = 0;
        for (int i = 1; i < n; i++)
        {
            int u, v, w;
            cin >> u >> v >> w;
            g[u].push_back({v, w});
            g[v].push_back({u, w});
        }
        dfs1(1, 0);
        struct item
        {
            int w;
            int c;
            void cut()
            {
                w = w / 2;
            }
            int eval() const
            {
                return c * (w - w / 2);
            }
            bool operator<(const item &rhs) const
            {
                return eval() < rhs.eval();
            }
        };
        priority_queue<item> heap;
        int ans = 0;
        int sum = 0;
        for (int i = 2; i <= n; i++)
        {
            heap.push({w[i], siz[i]});
            sum += w[i] * siz[i];
        }
        while (sum > s)
        {
            auto cur = heap.top();
            heap.pop();
            sum -= cur.eval();
            cur.cut();
            heap.push(cur);
            ans++;
        }
        cout << ans << endl;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int t;
        cin >> t;
        while (t--)
        {
            solve();
        }
    }
    
  • 相关阅读:
    【转】Java HotSpot(TM) 64-Bit Server VM warning: Insufficient space for shared memory file:
    kafka之partition分区及副本replica升级
    Rokid开发者社区skill之【历史上的今天】之简介+玩法+设计+实现+心得
    【转】批量删除redis中的key
    shell实现除法,保留小数点后N位
    [Django学习]中间件
    [Django学习]静态文件处理
    [Django学习]模板
    [Django学习]视图
    [Django学习]模型
  • 原文地址:https://www.cnblogs.com/mollnn/p/14383954.html
Copyright © 2020-2023  润新知