这题是基于一道经典的费用流模型。

将每天拆成两个点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 软件开发的更多相关文章

  1. BZOJ 1221 软件开发(费用流)

    容易看出这是显然的费用流模型. 把每天需要的餐巾数作为限制.需要将天数拆点,x’表示每天需要的餐巾,x’’表示每天用完的餐巾.所以加边 (s,x',INF,0),(x'',t,INF,0). 餐巾可以 ...

  2. 【BZOJ】【1221】【HNOI2001】软件开发

    网络流/费用流 说是这题跟餐巾计划一模一样……但我没做过啊……so sad 二分图建模是很好想的,但是要控制流量跟用了的毛巾一样多……oh my god 事实上对于每一天我们无论如何都是要消耗n[i] ...

  3. BZOJ 1221: [HNOI2001] 软件开发

    1221: [HNOI2001] 软件开发 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1428  Solved: 791[Submit][Stat ...

  4. 【BZOJ】1221: [HNOI2001] 软件开发(最小费用最大流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1221 先吐槽一下,数组依旧开小了RE:在spfa中用了memset和<queue>的版本 ...

  5. BZOJ 3280: 小R的烦恼 & BZOJ 1221: [HNOI2001] 软件开发

    3280: 小R的烦恼 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 399  Solved: 200[Submit][Status][Discuss ...

  6. BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)

    不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...

  7. 【BZOJ 1221】 1221: [HNOI2001] 软件开发 (最小费用流)

    1221: [HNOI2001] 软件开发 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1581  Solved: 891 Description ...

  8. [BZOJ 1221] [HNOI2001] 软件开发 【费用流 || 三分】

    题目链接:BZOJ - 1221 题目分析 算法一:最小费用最大流 首先这是一道经典的网络流问题.每天建立两个节点,一个 i 表示使用毛巾,一个 i' 表示这天用过的毛巾. 然后 i 向 T 连 Ai ...

  9. bzoj:1221;vijos 1552 软件开发

    Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...

  10. bzoj 1221 [HNOI2001] 软件开发 费用流

    [HNOI2001] 软件开发 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1938  Solved: 1118[Submit][Status][D ...

随机推荐

  1. Codeforces Round #319 (Div. 2) B Modulo Sum (dp,鸽巢)

    直接O(n*m)的dp也可以直接跑过. 因为上最多跑到m就终止了,因为前缀sum[i]取余数,i = 0,1,2,3...,m,有m+1个余数,m的余数只有m种必然有两个相同. #include< ...

  2. vue 修改端口

  3. Acronis.Disk.Director磁盘分区管理

    Acronis.Disk.Director分为for 专业版和服务器版的,我在生产环境中调整Windows2003跳板机使用的是Acronis.Disk.Director Server 10.0.20 ...

  4. 2018.3.3 多线程中继承Thread 和实现Runnable接口 的比较(通过售票案例来分析)

    多线程中继承Thread 和实现Runnable接口 的比较(通过售票案例来分析) 通过Thread来实现 Test.java package com.lanqiao.demo4; public cl ...

  5. Bootstrap标签页(Tab)插件事件

    事件 下表列出了标签页(Tab)插件中要用到的事件.这些事件可在函数中当钩子使用. 事件 描述 实例 show.bs.tab 该事件在标签页显示时触发,但是必须在新标签页被显示之前.分别使用 even ...

  6. fei33423 工作 职场 格言

    对老板: 1.  老板不知道你做的事情(目标设定) 2.  老板要的是规划(对上报告), 自己给自己设定 金字塔四位下的目标,各种维度.如何细化. 2.1 明确老板期望 2.2 与老板达成共识 2.3 ...

  7. ios下通过webservice获取数据

    经历了两天的摸索,终于成功获取了数据,因为公司要做一个停车入库的信息查询,所以需要访问webservice的接口,由于没有接触过webservice,所以第一天就是各种搜索资料,类库,各种尝试,甚至是 ...

  8. C# 获取Google Chrome的书签

    其实这个很简单,就是读取一个在用户目录里面的一个Bookmarks文件就好了. 先建立几个实体类 public class GoogleChrome_bookMark_meta_info { publ ...

  9. NOIP复习之1 数学数论

    noip一轮复习真的要开始啦!!! 大概顺序是这样的 1.数学 2.搜索贪心 3.数据结构 4.图论 5.dp 6.其他 数学 1.数论 数论被称为数学皇冠上的明珠,他的重要性主要在于它是其他学习的祖 ...

  10. python列表之append与extend方法比较

    append和extend是列表的两种添加元素方式,但这两种方式却又有些不同之处.那么不同之处在哪里呢,我们通过对二者的定义和实例来看一看. list.append() 1.定义:L.append(o ...