一道思路很好的题,因为篇幅太长赶时间,以下多数转自这里

【题目】
定义了一种蔬菜为: a i , s i , c i , x i a_i,s_i,c_i,x_i ai​,si​,ci​,xi​,有 n n n种蔬菜
意思是蔬菜的价格为 a i a_i ai​,第一份卖出时价格为 a i + s i a_i+s_i ai​+si​,一共有 c i c_i ci​份,每天会有 x i x_i xi​份过期;每天最多卖出 m m m份蔬菜,多组输入天数 d d d依次最大化收入。
n , m , d , T ≤ 1 0 5 n,m,d,T\leq 10^5 n,m,d,T≤105

【解题思路】
首先有一个费用流的做法是这样子的:首先对于蔬菜拆点,每一天拆出一个点,因为蔬菜可以购买的量逐渐递减,因此每一天向下一天连接流量为当前天减少 d d d的边,费用为 0 0 0,然后考虑把蔬菜卖出去,那么就是从一个蔬菜拆出来的某一天向汇点连边,因为限制每天购买的总量,所以再对于每一天的购买的蔬菜拆一个点,然后这一天的每一个蔬菜向这个点连容量为 i n f inf inf,费用为蔬菜费用的边,再从这个点向汇点连容量为 m m m,费用 为 0 为0 为0的边。显然源点向每个蔬菜的第一天连容量为蔬菜数量,费用为 0 0 0的边,至于第一次购买产生的额外贡献,我们把连的那条边拆出一个单位来,再额外链接一下容量为 1 1 1,费用为第一次购买产生的额外贡献的边。这样子连边就好了。

跳出来,往正解的方面想。
显然不难发现一个 O ( n Q ) O(nQ) O(nQ)的贪心,蔬菜会逐渐减少很不好做,我们倒过来,反过来考虑每一天,那么蔬菜的数量变成了每一天都增加每种蔬菜一定量,然后我们需要倒着买蔬菜就好了。可能需要数据结构什么的维护一下,但是大致的复杂度就是上述的东西。

我们现在再正着考虑,假设我们知道我们在 p p p天的时候的最优解中,买了哪些蔬菜,那么我们可以很容易的得到 p − 1 p-1 p−1天的答案,显然只需要把利润最小的那 m m m个蔬菜给去掉就好了,因为第 p − 1 p-1 p−1天可以购买的蔬菜不会少于第 p p p天,在第 p p p天能够买到的,在 p − 1 p-1 p−1天也一定能够买到。

前面说的不是很清楚,现在考虑如何求解第 p p p天的答案。我们既然是增加蔬菜,那么这个操作很容易维护,只需要搞一个堆出来,然后每次把当前所拥有的所有蔬菜全部拿出来贪心取就好了,稍微注意一下第一次选产生的额外贡献的细节就好。然后考虑如何递推回去,还是拿一个堆维护,同理注意一下第一次选产生的额外贡献。

既然这么讲了贪心怎么写,是不是觉得其实这就是一个模拟费用流的过程啊,倒推回去就是一个退流的过程,正推的贪心,显然每天只有那么几条路径,用堆维护等价于跑费用流。

复杂度 O ( n l o g n + q m ( l o g n + l o g q ) ) O(nlogn +qm(log\ n+log\ q)) O(nlogn+qm(log n+log q))

【参考代码】

#include<bits/stdc++.h>
#define pb push_back
#define mkp make_pair
#define fi first
#define se second
using namespace std;typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,P=1e5;
int n,m,Q,sum;
int used[N],vis[N];
ll ans[N];
vector<int>d[N];
stack<pii>s;
priority_queue<pii>q;int read()
{int ret=0;char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) ret=ret*10+(c^48),c=getchar();return ret;
}struct data
{int a,s,c,x;void rd(){a=read();s=read();c=read();x=read();}
}a[N];int main()
{#ifndef ONLINE_JUDGEfreopen("BZOJ4946.in","r",stdin);freopen("BZOJ4946.out","w",stdout);
#endifn=read();m=read();Q=read();for(int i=1;i<=n;++i) a[i].rd();for(int i=1;i<=n;++i) if(!a[i].x) d[P].pb(i); else d[min(P,(a[i].c+a[i].x-1)/a[i].x)].pb(i);for(int i=P;i;--i){for(int j=0,id;j<(int)d[i].size();++j) id=d[i][j],q.push(mkp(a[id].a+a[id].s,id));for(int j=m;j && !q.empty();){int w=q.top().fi,v=q.top().se;q.pop();if(!vis[v]){vis[v]=1;ans[P]+=w;++used[v];--j;if(a[v].c>1) q.push(mkp(a[v].a,v));}else{int res=min(j,a[v].c-used[v]-(i-1)*a[v].x);ans[P]+=(ll)res*w;used[v]+=res;j-=res;if(used[v]^a[v].c) s.push(mkp(a[v].a,v));}}while(!s.empty()) q.push(s.top()),s.pop();}while(!q.empty()) q.pop();for(int i=1;i<=n;++i) sum+=used[i];for(int i=1;i<=n;++i) if(used[i]==1) q.push(mkp(-a[i].s-a[i].a,i));else if(used[i]) q.push(mkp(-a[i].a,i));for(int i=P-1;i;--i){ans[i]=ans[i+1];while(sum>i*m && !q.empty()){int w=-q.top().fi,v=q.top().se;q.pop();if(used[v]>1){int res=min(sum-i*m,used[v]-1);used[v]-=res;sum-=res;ans[i]-=(ll)res*w;if(used[v]==1) q.push(mkp(-a[v].a-a[v].s,v));else q.push(mkp(-a[v].a,v));}else --sum,--used[v],ans[i]-=w;}}while(Q--) printf("%lld\n",ans[read()]);return 0;
}

【总结】
niubi

【贪心+堆/模拟费用流增广】BZOJ4946 [NOI2017]蔬菜相关推荐

  1. 【贪心 / 线段树模拟费用流增广】BZOJ4977 [Lydsy八月月赛] 跳伞求生

    [题目] 原题地址 有nn个队友和mm个敌人,每个队友有一个攻击力aia_i,每个敌人有攻击力bib_i和价值cic_i.你可以选择若干个队友,每个队友ii分别去怼一个敌人jj,当ai>bja_ ...

  2. UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)

    题目链接 http://uoj.ac/contest/47/problem/455 题解 模拟费用流,一个非常神奇的东西. 本题即为WC2019 laofu的讲课中的Problem 8,经典的老鼠进洞 ...

  3. [UOJ455][UER #8]雪灾与外卖——堆+模拟费用流

    题目链接: [UOJ455]雪灾与外卖 题目描述:有$n$个送餐员(坐标为$x_{i}$)及$m$个餐厅(坐标为$y_{i}$,权值为$w_{i}$),每个送餐员需要前往一个餐厅,每个餐厅只能容纳$c ...

  4. UOJ #455.【UER #8】雪灾与外卖 堆模拟费用流

    题意 有n个人和m家商店,每个人都要买一道菜.第i个人的坐标是a[i],第j家商店的坐标是y[i],有c[i]道菜且每道菜价格为w[i],每个人还要花费其到商店距离的路费,问最小花费. n,m≤105 ...

  5. BZOJ3291Alice与能源计划——匈牙利算法+模拟费用流

    题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验.为 了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...

  6. BZOJ 4946: [Noi2017]蔬菜 模拟费用流

    title BZOJ 4946 LUOGU 3826 简化题意: 定义了一种蔬菜为:\(ai,si,ci,xi\),意思是蔬菜的价格为 \(a_i\),第一份卖出时价格为 \(a_i+s_i\),一共 ...

  7. BZOJ 5326 [JSOI2017]博弈 (模拟费用流、线段树)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5326 题解 终于成为第8个A掉这题的人--orz tzw神仙早我6小时 本以为这东西常数 ...

  8. BZOJ 1920 Luogu P4217 [CTSC2010]产品销售 (模拟费用流、线段树)

    题目链接 (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=1920 (luogu) https://www.luogu.org/prob ...

  9. BZOJ 4849 [NEERC2016] Mole Tunnels (模拟费用流)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4849 题解 其实也是模拟费用流,但是这道题和一般的题目不一样,这道题是在一个完全二叉树上 ...

最新文章

  1. 【非专业评测】发蜡、发膏、发泥、发油、啫喱、发膜、发胶、干胶、发棒、摩丝
  2. Mac下使用crontab来实现定时任务
  3. Arduino(新手之路1)
  4. Swift与C++混编 OpenCV初体验 图片打码~
  5. 【PHP发展史】PHP5.2 到 PHP5.6 中新增的功能详解
  6. 解决MySQL查询数据不一致诟病
  7. jenkins搭建_如何搭建移动端自动化测试平台?没错,就用Jenkins!
  8. 使用ASP.NET Core,JavaScript,PostegreSql和ChartJs的动态仪表板Web应用程序
  9. jvm_tool jconsole/ jprofiler/ JProbe/ VirtualVm/ TPV/ YourKit/ ITCAM/ MAT/ MDD4J
  10. Hive学习笔记(二)——数据模型
  11. 基于Thinkphp开发的网页点餐收银系统SAAS模式
  12. Mybatis generator 生成xml文件时覆盖原文件
  13. CS信息系统建设和服务认证都有哪些等级?系统集成企业如何评估申报CS认证等级?
  14. 服装标准中纰裂试验方法的比较与探讨
  15. 2. Spring Boot使用Apache Curator实现分布式锁(可重入排它锁)「第四章 ZooKeeper Curator应用场景实战」「架构之路ZooKeeper理论和实战」
  16. 购物车二级列表联动以及价格计算
  17. 支付宝余额提现收手续费了
  18. Google map地图限制显示区域、拖拽范围
  19. 服务器带宽什么意思?服务器带宽多少合适?
  20. 科技公司的域名大战!

热门文章

  1. 分享88个HTML旅游交通模板,总有一款适合您
  2. 如何写一封稍微像样的求职邮件
  3. 怎样删除微信朋友圈的内容?超简单的方法免费分享!
  4. 碳中和推动第四次工业革命
  5. windows设置CPU主频
  6. 基于中国剩余定理的秘密共享方案(miracl库)
  7. HCIP路由交换的三门考试
  8. 消除VMware启动虚拟机时的floppy0提示的方法
  9. 注意BeanPostProcessor启动时对依赖Bean的“误伤”陷阱(is not eligible for getting processed by all...)
  10. windows Bat 批命令 教程