• CF 730 C.Bulmart


    C. Bulmart

    题目大意

    给定一张\(n\)个点\(m\)条边的无向图,边权为\(1\)。有\(w\)个商品信息,第\(i\)个商品在\(c_i\)点售卖,有 \(k_i\)件,单价 \(p_i\),有\(q\)个询问,每组询问问在第\(g_i\)点,要订购 \(r_i\)件商品,总价格不高于 \(a_i\)。要求订购的最远的点距离\(g_i\)点最近。问该距离,或告知不可行。\(n, w \leq 5000, m \leq 5000, q \leq 1000\)

    解题思路

    注意到范围都不大,那么对于每个询问,从\(g_i\)点开始BFS,把BFS到的商品加入可购买的列表里,购买自然是根据单价从小到达选择,直到购买\(r_i\)件。看价格是否大于 \(a_i\),不大于则当前距离就为答案。

    用优先队列维护当前可选择购买的商品的最小值。

    即优先队列里始终保持有不超过\(r_i\)件的商品,当有新商品加入时,自然是剔除里面单价最高的商品,然后加入当前商品(当然该商品单价小于被剔除商品的单价)。时间复杂度为 \(O(nq\log n)\)

    神奇的代码
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    int main(void) {
        ios::sync_with_stdio(false); 
        cin.tie(0); cout.tie(0);
        int n;
        cin >> n;
        priority_queue<pair<int, int>> tt;
        int minn = 1e9 + 7;
        for(int i = 0; i < n; ++ i){
            int x;
            cin >> x;
            minn = min(minn, x);
            tt.push({x, i});
        }
        vector<pair<int, int>> ans;
        vector<int> down(n, 0);
        int leff = 0;
        int cc = 0;
        while(tt.top().first != minn){
            auto t1 = tt.top();
            tt.pop();
            auto t2 = tt.top();
            tt.pop();
            if (t2.first == minn){
                if ((int)ans.size() - down[t1.second] >= t1.first - minn){
                    leff = t1.second;
                    cc = t1.first - minn;
                    break;
                }else{
                    minn = max(minn - 1, 0);
                }
            }
            ans.push_back({t1.second, t2.second});
            down[t1.second] ++;
            down[t2.second] ++;
            t1.first = max(t1.first - 1, 0);
            t2.first = max(t2.first - 1, 0);
            tt.push(t1);
            tt.push(t2);
        }
        cout << minn << '\n';
        cout << ans.size() << '\n';
        string s (n, '0');
        for(auto i : ans){
            s[i.first] = '1';
            s[i.second] = '1';
            if (i.first != leff && i.second != leff && cc)
                s[leff] = '1';
            cout << s << '\n';
            s[i.first] = '0';
            s[i.second] = '0';
            if (i.first != leff && i.second != leff && cc){
                s[leff] = '0';
                -- cc;
            }
        }
        return 0;
    }
    


  • 相关阅读:
    react中关于render渲染次数的性能优化
    ES6中六种常用的传出调用方式
    在Vue-cli中得xxx.vue文件中快速生成组件模板
    如何在Vue-cli中关闭ESLint以及关闭部分ESLint验证
    使用ES6删除对象中某些属性
    React中使用遍历
    git commit报错解决,绕过代码检查
    React学习——子组件给父组件传值
    React学习——通过模态框中的表单,学习父子组件之间传值
    学习axios
  • 原文地址:https://www.cnblogs.com/Lanly/p/16104177.html
Copyright © 2020-2023  润新知