2022-04-05 22:00阅读: 38评论: 0推荐: 0

CF 730 C.Bulmart

C. Bulmart

题目大意

给定一张n个点m条边的无向图,边权为1。有w个商品信息,第i个商品在ci点售卖,有 ki件,单价 pi,有q个询问,每组询问问在第gi点,要订购 ri件商品,总价格不高于 ai。要求订购的最远的点距离gi点最近。问该距离,或告知不可行。n,w5000,m5000,q1000

解题思路

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

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

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

神奇的代码
#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;
}


本文作者:~Lanly~

本文链接:https://www.cnblogs.com/Lanly/p/16104177.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   ~Lanly~  阅读(38)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.