bzoj1061 志愿者招募

Description

申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难

题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要

Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用

是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这

并不是他的特长!于是布布找到了你,希望你帮他设计一种最优的招募方案。

Input

第一行包含两个整数N, M,表示完成项目的天数和可以招募的志愿者的种类。 接下来的一行中包含N 个非负

整数,表示每天至少需要的志愿者人数。 接下来的M 行中每行包含三个整数Si, Ti, Ci,含义如上文所述。为了

方便起见,我们可以认为每类志愿者的数量都是无限多的。

Output

仅包含一个整数,表示你所设计的最优方案的总费用。

Sample Input

3 3

2 3 4

1 2 2

2 3 5

3 3 2

Sample Output

14

HINT

1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过2^31-1。

解法

此题真是神坑,根据流量平衡可以得出解法。

我们设第\(i\)类志愿者用了\(X_i\)人,\(Y \ge 0\),可以得出:

\(\sum X_i = Y_j + A_j (S_i \le j \le T_i) \tag{1}\)

考虑第\(i\)天与第\(i+1\)天:

\(\sum X_i = Y_{j+1} + A_{j+1} (S_i \le j + 1 \le T_i) \tag{2}\)

1,2做差可得:

\(\sum_{T_i=j} X_i - \sum_{S_i=j+1} X_i = Y_j - Y_{j+1} + A_j - A_{j+1}\)

模仿流量平衡方程,我们就可以建立费用流模型,之后用朴素的mcf都可以过。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define inf 0x3f3f3f3f
typedef int edge[50003], vert[1003];
edge nt, c, w, to;
vert d, hd, q, from;
int ce, T;
bool inq[1003];
inline void adde(int x, int y, int z, int v) {
to[ce] = y, nt[ce] = hd[x];
c[ce] = z, w[ce] = v;
hd[x] = ce++;
}
#define nxt(i) (++(i)>=1003?i=0:i)
inline bool SPFA() {
static int u, v, i, l, r;
for (i = 1; i <= T; ++i) d[i] = inf;
d[0] = 0; q[0] = 0; from[0] = -1;
for (l = 0, r = 1; l ^ r; ) {
u = q[l]; nxt(l);
for (i = hd[u]; ~i; i = nt[i])
if (c[i] && d[v = to[i]] > w[i] + d[u]) {
d[v] = w[i] + d[u];
from[v] = i;
if (!inq[v]) inq[v] = true, q[r] = v, nxt(r);
}
inq[u] = false;
}
return d[T] < inf;
} inline int mcf() {
static int f, e, ret;
for (f = inf, e = from[T], ret = 0; ~e; e = from[to[e^1]]) f = min(f, c[e]), ret += w[e];
for (e = from[T]; ~e; e = from[to[e^1]]) c[e] -= f, c[e^1] += f;
return f * ret;
} int main() {
int n, m, i, x, y, v;
memset(hd, -1, sizeof hd);
scanf("%d%d", &n, &m);
T = n + 2;
for (y = 0, i = 1; i <= n; ++i) {
scanf("%d", &x);
v = x - y;
y = x;
if (v > 0) adde(0, i, v, 0), adde(i, 0, 0, 0);
else adde(i, T, -v, 0), adde(T, i, 0, 0);
adde(i + 1, i, inf, 0), adde(i, i + 1, 0, 0);
}
adde(n + 1, T, y, 0), adde(T, n + 1, 0, 0);
while (m--) {
scanf("%d%d%d", &x, &y, &v);
++y;
adde(x, y, inf, v), adde(y, x, 0, -v);
}
v = 0;
while (SPFA())
v += mcf();
printf("%d\n", v);
return 0;
}

其实我们可以发现1,2就是线性规划的标准形式,直接单纯形法。

#include <cmath>
#include <cstdio>
inline int gi() {
static int a; static char c;
while ((c = getchar()) < '0'); a = c - '0';
while ('-' < (c = getchar())) a = (a << 3) + (a << 1) + c - '0';
return a;
}
const int N = 1003, M = 10003;
const double inf = 1e9, eps = 1e-9;
int n, m;
double a[M][N], b[M], c[N], v;
void pivot(int l, int e) {
static int i, j;
b[l] /= a[l][e];
for (j = 1; j <= n; ++j) if (j ^ e) a[l][j] /= a[l][e];
a[l][e] = 1 / a[l][e];
for (i = 1; i <= m; ++i)
if ((i ^ l) && fabs(a[i][e]) > 0) {
b[i] -= a[i][e] * b[l];
for (j = 1; j <= n; ++j) if (j ^ e) a[i][j] -= a[i][e] * a[l][j];
a[i][e] = -a[i][e] * a[l][e];
}
v += c[e] * b[l];
for (j = 1; j <= n; ++j) if (j ^ e) c[j] -= c[e] * a[l][j];
c[e] = -c[e] * a[l][e];
}
double simplex() {
int e, l, i;
double mn;
while (true) {
for (e = 1; e <= n; ++e) if(c[e] > eps) break;
if (e > n) return v;
for (i = 1, mn = inf; i <= m; ++i)
if (a[i][e] > eps && mn > b[i] / a[i][e]) mn = b[i] / a[i][e], l = i;
if (mn == inf) return inf;
pivot(l, e);
}
}
int main() {
int i, j, s, t;
n = gi(), m = gi();
for (i = 1; i <= n; ++i) c[i] = gi();
for (i = 1; i <= m; ++i) {
s = gi(), t = gi();
for (j = s; j <= t; ++j) a[i][j] = 1;
b[i] = gi();
}
printf("%d", (int)(simplex() + 0.5));
return 0;
}

bzoj1061 志愿者招募的更多相关文章

  1. BZOJ-1061 志愿者招募 线性规划转最小费用最大流+数学模型 建模

    本来一眼建模,以为傻逼题,然后发现自己傻逼...根本没想到神奇的数学模型..... 1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 ...

  2. [NOI2008][bzoj1061] 志愿者招募 [费用流+巧妙的建图]

    题面 传送门 思路 引入:网络流? 看到这道题,第一想法是用一个dp来完成决策 但是,显然这道题的数据并不允许我们进行dp,尤其是有10000种志愿者的情况下 那么我们就要想别的办法来解决: 贪心?这 ...

  3. [NOI2008] [bzoj1061] 志愿者招募

    还是一道费用流的题目.话不多说,进入正题. 题意:给定n个点和m种从l到r覆盖一层的费用,求满足所有点的覆盖层数都大等于权值的最小费用 分析:要做到区间修改,看似比较麻烦. 用差分把区间修改变成单点修 ...

  4. [BZOJ1061][Noi2008]志愿者招募

    [BZOJ1061][Noi2008]志愿者招募 试题描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿 ...

  5. 网络流解线性规划问题 BZOJ1061: [Noi2008]志愿者招募

    线性规划定义: 在给定有限的资源和竞争约束情况下,很多问题都可以表述为最大化或最小化某个目标.如果可以把目标指定为某些变量的线性函数,而且如果可以将资源约束指定为这些变量的等式或不等式,则得到了一个线 ...

  6. 【BZOJ1061】【NOI2008】志愿者招募

    [BZOJ1061][NOI2008]志愿者招募 题面 BZOJ 题解 我们设每类志愿者分别招募了\(B[i]\)个 那么,我们可以得到一系列的方程 \[\sum_{S[i]\leq x\leq T[ ...

  7. 【BZOJ1061/3265】[Noi2008]志愿者招募/志愿者招募加强版 单纯形法

    [BZOJ1061][Noi2008]志愿者招募 Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募 ...

  8. bzoj1061: [Noi2008]志愿者招募

    线性规划与费用流.http://www.cnblogs.com/iiyiyi/p/5616080.html.数组范围开错了!!!然后2.31-1=0x7fffffff!=0x7f7f7f7f. 开始以 ...

  9. 【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 5291  Solved: 3173[Submit][Stat ...

随机推荐

  1. SB淘宝api的奇葩问题! 一则服务器无法访问淘宝api

    <?xml version="1.0" encoding="utf-8" ?><error_response><code>3 ...

  2. 硬盘安装win8系统方法汇总

    从硬盘安装 (推荐)硬盘安装方法一 使用Nt6 hdd installer进行安装,此方法适合XP,vista, Windows 7等系统. 下载Nt6 hdd installer(Win8硬盘安装工 ...

  3. MULE-ET0 、 ET1、ET2、PT1、PT2

    设计验证阶段中的五个样车试制概念 骡子车( mule car ) ET0 第一轮设计工程样车试制 ET1 第二轮设计工程样车试制 ET2 第一轮产品工装样车试制 PT1 第二轮产品工装样车试制 PT2 ...

  4. 【转】Xshell 十个技巧

    原文:http://www.cnblogs.com/wanhl/archive/2012/10/17/2727607.html 一.帐号密码保存.可以保存多个vps登陆信息,免去每次输入的烦恼. 二. ...

  5. cocos2d-x 不规则形状按钮的点击判定

    cocos2d-x 不规则形状按钮的点击判定 原理: 1.OpeGL ES提供了glReadPixels[^footnote]函数,来获取当前framebuffer上的像素数据 2.cocos2d-x ...

  6. opencv---cvor

    void cvXor计算两个数组中的每个元素的按位异或. void cvXor (const CvArr* src1, const CvArr* src2, CvArr* dst, const CvA ...

  7. Spring Boot 系列教程6-全局异常处理

    @ControllerAdvice源码 package org.springframework.web.bind.annotation; import java.lang.annotation.Ann ...

  8. 图像操作相关 With Quartz 2D

    本文将为大家介绍常见的IOS图像处理操作包括以下四部分:旋转,缩放,裁剪以及像素和UIImage之间的转化,主要使用的知识是quartz2D.Quartz2D是CoreGraphics框架中的一个重要 ...

  9. 添加一个Application Framework Service

    如何添加一个Application Framework Service(without native code)? 1.本文参照AlarmManagerService实现一个简单的Applicatio ...

  10. 1--OC -- HelloWorld

      一.点击Xcode,选择“Create a new Xcode project” 二.左边选择“OS X Application”,右边选择“Command Line Tool”,Next 三.输 ...