BZOJ-1221 软件开发
这题是基于一道经典的费用流模型。
将每天拆成两个点i和j,新增源和汇并建立六种边:
1.从源出发到每个i点,flow为+∞,cost为每条新餐巾的价值,表示这一天所使用的餐巾中来自购买的餐巾
2.从源出发到每个j点,flow为每天所需的餐巾数,cost为0,表示这一天最多可使用的餐巾
3.从每个i点出发至汇,flow为每天所需的餐巾数,cost为0,表示这一天应该使用的餐巾
4.从每个j点出发至下一个j点,flow为+∞,cost为0,表示这一天使用后的餐巾移至下一天
5.从每个j点出发至下a个i点,flow为+∞,cost为第一种消毒的费用,表示这一天所使用的餐巾中来自第一种消毒后的餐巾
6.从每个j点出发至下b个i点,flow为+∞,cost为第二种消毒的费用,表示这一天所使用的餐巾中来自第二种消毒后的餐巾
然后最小费用最大流跑之。
基于图的稀疏,我用ZKW费用流实现。
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <deque>
using namespace std;
typedef long long ll;
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(c))
#define travel(x) for(edge *p=fir[x]; p; p=p->n) if (p->f)
#define pb push_back
#define pf push_front
#define maxv 2009
#define maxm 30009
#define inf 0x7fffffff
int read()
{
int x=0; char ch=getchar();
while (!isdigit(ch)) ch=getchar();
while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x;
} struct edge{int y, f, c; edge *n, *pair;} e[maxm], *fir[maxv], *pt;
inline void Init(){pt=e; clr(fir, 0);}
inline void Add(int x, int y, int f, int c)
{pt->y=y, pt->f=f, pt->c=c, pt->n=fir[x]; fir[x]=pt++;}
inline void AddE(int x, int y, int f, int c)
{Add(x, y, f, c); Add(y, x, 0, -c); fir[x]->pair=fir[y], fir[y]->pair=fir[x];}
int S, T, V, d[maxv]; ll cost=0;
int dist[maxv], st[maxv];
bool b[maxv];
deque <int> q;
inline void spfa()
{
rep(i, 1, V) d[i]=inf, b[i]=0; q.clear();
q.pb(S), d[S]=0, b[S]=1;
while (!q.empty())
{
int x=q.front(), y; q.pop_front(); b[x]=0;
travel(x) if (d[y=p->y] > d[x]+p->c)
{
d[y]=d[x]+p->c;
if (!b[y]) b[y]=1, (!q.empty() && d[q.front()]>d[y]) ? q.pf(y) : q.pb(y);
}
}
}
void dfs(int now)
{
b[now]=1; int y;
travel(now)
if (d[now]+p->c==d[y=p->y] && !b[y])
dist[y]=dist[now]-p->c, dfs(y);
}
int aug(int now, int flow)
{
if (now==T) {cost+=flow*(dist[S]-dist[T]); return flow;}
b[now]=1; int rec=0, y, ret;
travel(now) if (!b[y=p->y])
{
if (dist[now]==dist[y]+p->c)
{
ret=aug(y, min(flow-rec, p->f));
p->f-=ret, p->pair->f+=ret;
if ((rec+=ret)==flow) return flow;
}
else st[y]=min(st[y], dist[y]+p->c-dist[now]);
}
return rec;
}
inline bool relabel()
{
int a=inf;
rep(i, 1, V) if (!b[i]) a=min(a, st[i]);
if (a==inf) return 0;
rep(i, 1, V) if (b[i]) dist[i]+=a;
return 1;
}
inline void costflow()
{
spfa();
clr(b, 0); clr(dist, 0);
dfs(S);
while(1)
{
rep(i, 1, V) st[i]=inf;
while(1)
{
rep(i, 1, V) b[i]=0;//clr(b, 0);
if (!aug(S, inf)) break;
}
if (!relabel()) break;
}
} int n;
int main(){
Init(); n=read(); S=n*2+1; T=V=n*2+2;
int a=read(), b=read(), f=read(), fa=read(), fb=read();
rep(i, 1, n-a) AddE(i*2, (i+a+1)*2-1, inf, fa);
rep(i, 1, n-b) AddE(i*2, (i+b+1)*2-1, inf, fb);
rep(i, 1, n) a=read(), AddE(S, i*2-1, inf, f), AddE(S, i*2, a, 0), AddE(i*2-1, T, a, 0);
rep(i, 1, n-1) AddE(i*2, i*2+2, inf, 0);
costflow(); printf("%lld\n", cost);
return 0;
}
BZOJ-1221 软件开发的更多相关文章
- BZOJ 1221 软件开发(费用流)
容易看出这是显然的费用流模型. 把每天需要的餐巾数作为限制.需要将天数拆点,x’表示每天需要的餐巾,x’’表示每天用完的餐巾.所以加边 (s,x',INF,0),(x'',t,INF,0). 餐巾可以 ...
- 【BZOJ】【1221】【HNOI2001】软件开发
网络流/费用流 说是这题跟餐巾计划一模一样……但我没做过啊……so sad 二分图建模是很好想的,但是要控制流量跟用了的毛巾一样多……oh my god 事实上对于每一天我们无论如何都是要消耗n[i] ...
- BZOJ 1221: [HNOI2001] 软件开发
1221: [HNOI2001] 软件开发 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1428 Solved: 791[Submit][Stat ...
- 【BZOJ】1221: [HNOI2001] 软件开发(最小费用最大流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1221 先吐槽一下,数组依旧开小了RE:在spfa中用了memset和<queue>的版本 ...
- BZOJ 3280: 小R的烦恼 & BZOJ 1221: [HNOI2001] 软件开发
3280: 小R的烦恼 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 399 Solved: 200[Submit][Status][Discuss ...
- BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...
- 【BZOJ 1221】 1221: [HNOI2001] 软件开发 (最小费用流)
1221: [HNOI2001] 软件开发 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1581 Solved: 891 Description ...
- [BZOJ 1221] [HNOI2001] 软件开发 【费用流 || 三分】
题目链接:BZOJ - 1221 题目分析 算法一:最小费用最大流 首先这是一道经典的网络流问题.每天建立两个节点,一个 i 表示使用毛巾,一个 i' 表示这天用过的毛巾. 然后 i 向 T 连 Ai ...
- bzoj:1221;vijos 1552 软件开发
Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...
- bzoj 1221 [HNOI2001] 软件开发 费用流
[HNOI2001] 软件开发 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1938 Solved: 1118[Submit][Status][D ...
随机推荐
- Round #322 (Div. 2) 581D Three Logos (模拟)
先枚举两个矩形,每个矩形横着放或竖着放,把一边拼起来, 如果不是拼起来有缺口就尝试用第三个矩形去补. 如果没有缺口就横着竖着枚举一下第三个矩形和合并的矩形x或y拼接. #include<bits ...
- Android(java)学习笔记135:SQLite数据库(表)的创建 以及 SQLite数据库的升级
一.数据库的创建 1.文件的创建 //引用,如果文件不存在是不会创建的 File file = new File("haha.txt"): //输出流写数据 ...
- 七、vue中将token存到cookie
使用js-cookie工具: 1.npm i js-cookie //安装2.import Cookies from 'js-cookie' //引用 // 存入cookie:Cookies.set( ...
- 2018.3.26 Linux下学习命令
Linux下的终端文件颜色说明 ---color[=WHEN] 用色彩辨别文件类型 WHEN 可以是'never'.'always'或'auto'其中之一 白色:表示普通文件 蓝色:表示目录 绿色:表 ...
- DROP GROUP - 删除一个用户组
SYNOPSIS DROP GROUP name DESCRIPTION 描述 DROP GROUP 从数据库中删除指定的组.组中的用户不被删除. 组中的用户不被删除. PARAMETERS 参数 n ...
- Java中的ArrayList类和LinkedList
集合的体系: ----------| Collection 单列集合的根接口----------------| List 如果实现了List接口的集合类,具备的特点: 有序,可重复.--------- ...
- ARC中__weak;__strong;__unsafe_unretained;修饰词
测试代码: // Human.h代码 @interface Human : NSObject @property (nonatomic, weak) Cat *pinkCat; @property ( ...
- 20181111 计时器影响DOM点击事件的逻辑
今天在群里看见一个人在问"点击按钮使图片产生旋转为什么要使用计时器来实现",我自己操作了一遍她的代码才发现里面的逻辑实现很有意思,所以写出来分享一下. 她的代码是这样写的: < ...
- CentOS 编译安装PHP5.6(7以上也通用)
由于公司有新服务器需要构建一套LNMP平台,且需要编译安装各个部件,所以记录下此文章. 这是安装PHP涉及到的软件包(可以自行决定使用哪个版本): ├── libiconv-1.15.tar.gz ├ ...
- NOIP2016 toy
题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉 ...