题面

N

N

N 种糖果,

M

M

M 个小孩子,第

i

i

i 种糖果有

A

i

A_i

Ai​ 个,第

i

i

i 个孩子不能有超过

B

i

B_i

Bi​ 个同种类型的糖果,第

i

i

i 个孩子的糖果总数不能超过

C

i

C_i

Ci​ 。

合理分配糖果,问能分配出去的最大糖果数。

N

,

M

2

e

5

N,M\leq 2e5

N,M≤2e5 。

题解

不难想到,这就是最大流啊!

可是我们完全没法建图,更是跑不过。

那,模拟最大流?

您可以试试,不过我们这道题的正解是用最大流最小割定理

最大流等于最小割,此题最大流不好求,我们就求最小割。

一共有三类边,一类是源点连向每种糖果的边,权值为

A

i

A_i

Ai​ ,第二类是糖果和孩子之间的连边,孩子的每条入边边权都是

B

i

B_i

Bi​ ,第三类是孩子连向汇点的边,边权为

C

i

C_i

Ci​ 。

我们割掉一些边使得源点到不了汇点,可以逐个考虑。首先,糖果之间的顺序不重要,我们先把糖果按

A

i

A_i

Ai​ 从小到大排个序,割掉的边一定是个前缀。我们枚举割掉多少边,对应就已经有多少种糖果和源点不连通了,剩下的糖果,设一共有

X

X

X 种,要保证割掉第二类或第三类边后不与汇点连通。由于我们知道每种糖果与每个孩子都是存在边的,因此剩下的就是对于每个小孩子,独立地选择是割掉自己连向汇点的边(

C

i

C_i

Ci​),还是割掉从源点连过来的边(

X

B

i

X\cdot B_i

X⋅Bi​),选两者的较小值。由于决策是关于

X

X

X 单向变化的(

X

X

X 小到一定程度就不割

C

i

C_i

Ci​ 了),我们可以预处理出每个孩子决策变化时的

X

X

X 值。

时间复杂度

O

(

n

log

n

)

O(n\log n)

O(nlogn) ,基排可以

O

(

n

)

O(n)

O(n) 。

CODE

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<ctime>
#include<queue>
#include<bitset>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 200005
#define LL long long
#define DB double
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define eps (1e-4)
#define BI bitset<MAXN>
LL read() {
LL f=1,x=0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f*x;
}
void putpos(LL x) {
if(!x) return ;
putpos(x/10); putchar('0'+(x%10));
}
void putnum(LL x) {
if(!x) putchar('0');
else if(x < 0) putchar('-'),putpos(-x);
else putpos(x);
}
inline void AIput(LL x,char c) {
putnum(x); putchar(c);
}
int n,m,s,o,k;
LL a[MAXN],b[MAXN],c[MAXN];
vector<int> bu[MAXN];
int main() {
n = read();m = read();
for(int i = 1;i <= n;i ++) {
a[i] = read();
}
sort(a + 1,a + 1 + n);
LL sm = 0,sb = 0;
for(int i = 1;i <= m;i ++) b[i] = read();
for(int i = 1;i <= m;i ++) {
c[i] = read();
sm += c[i];
int le = (int)max(0ll,(LL)n - (c[i]/b[i]));
if(le <= 0) {
sm -= c[i];
sm += n*1ll*b[i];
sb += b[i];
}
else bu[le].push_back(i);
}
LL ans = sm;
for(int i = 1;i <= n;i ++) {
sm -= sb;
sm += a[i];
for(int j = 0;j < (int)bu[i].size();j ++) {
int y = bu[i][j];
sm -= c[y]; sm += (n-i) *1ll* b[y];
sb += b[y];
}
ans = min(ans,sm);
}
printf("%lld\n",ans);
return 0;
}

最新文章

  1. CentOS7网络配置
  2. 20145235 《Java程序设计》第10周学习总结
  3. 理解和配置 Linux 下的 OOM Killer
  4. 将UIWebView显示的内容转为图片和PDF
  5. 深入学习Redis(5):集群
  6. mysql 删除重复数据
  7. SQL server 2012 数据库日志缓存过大
  8. python基础——dict和set(字典和集合)
  9. POJ 2752 (kmp求所有公共前后缀长度)
  10. 服务器最大TCP连接数及调优汇总
  11. 【PyTorch深度学习60分钟快速入门 】Part0:系列介绍
  12. 编写JDBC框架:(策略设计模式)
  13. LeetCode: Best Time to Buy and Sell Stock II 解题报告
  14. SQL Server常用SQL集合
  15. HDU 1950(LIS)
  16. 认识loadrunner及相关性能参数
  17. 图像边缘检測--OpenCV之cvCanny函数
  18. 怎样快速掌握一个用你没学过的框架写的PHP项目?
  19. Hibernate学习11——配置Hibernate二级缓存
  20. 【转】odoo装饰器:model

热门文章

  1. CentOS搭建BWAPP靶场并安装docker
  2. c++ 乘法逆元
  3. JAVA学习之第一个HelloWorld程序
  4. 将Hexo搭建到自己的服务器上
  5. 关于个人全栈项目【臻美IT】博客类出现的问题以及解决方法
  6. linux安装源码包指定安装目录
  7. 记录一下MySql update会锁定哪些范围的数据
  8. 分享自己平时使用的socket多客户端通信的代码技术点和软件使用
  9. 03 转换css元素的类别
  10. linux shell的配置文件执行顺序