转自神犇:https://www.cnblogs.com/jianglangcaijin/p/3799759.html

题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这并不是他的特长!于是布布找到了你,希望你帮他设计一种最 优的招募方案。

思路:

这个一个类影响一个区间,所以并不能像HDU - 3572 一样 按时间拆点

一系列每个变量等式左右各只出现一次的等式,然后用流量平衡建图即可。

所以列出公式求解

例如一共需要4天,四天需要的人数依次是4,2,5,3。有5类志愿者,如下表所示:

设雇佣第i类志愿者的人数为X[i],每个志愿者的费用为V[i],第j天雇佣的人数为P[j],则每天的雇佣人数应满足一个不等式,如上表所述,可以列出

P[1]=X[1]+X[2]>=4

P[2]=X[1]+X[3]>=2

P[3]=X[3]+X[4]+X[5]>=5

P[4]=X[5]>=3

对于第i个不等式,添加辅助变量Y[i](Y[i]>=0),可以使其变为等式

P[1]=X[1]+X[2]-Y[1]=4

P[2]=X[1]+X[3]-Y[2]=2

P[3]=X[3]+X[4]+X[5]-Y[3]=5

P[4]=X[5]-Y[4]=3

在上述四个等式上下添加P[0]=0,P[5]=0,每次用下边的式子减去上边的式子,得出

① P[1]-P[0]=X[1]+X[2]-Y[1]=4

② P[2]-P[1]=X[3]-X[2]-Y[2]+Y[1]=-2

③ P[3]-P[2]=X[4]+X[5]-X[1]-Y[3]+Y[2]=3

④ P[4]-P[3]=-X[3]-X[4]+Y[3]-Y[4]=-2

⑤ P[5]-P[4]=-X[5]+Y[4]=-3

观察发现,每个变量都在两个式子中出现了,而且一次为正,一次为负.所有等式右边和为0.我们将最后的五个等式进一步变形,得出以下结果

① -X[1]-X[2]+Y[1]+4=0

② -X[3]+X[2]+Y[2]-Y[1]-2=0

③ -X[4]-X[5]+X[1]+Y[3]-Y[2]+3=0

④ X[3]+X[4]-Y[3]+Y[4]-2=0

⑤ X[5]-Y[4]-3=0

可 以发现,每个等式左边都是几个变量和一个常数相加减,右边都为0,恰好就像网络流中除了源点和汇点的顶点都满足流量平衡。每个正的变量相当于流入该顶点的 流量,负的变量相当于流出该顶点的流量,而正常数可以看作来自附加源点的流量,负的常数是流向附加汇点的流量。因此可以据此构造网络,求出从附加源到附加 汇的网络最大流,即可满足所有等式。而我们还要求费用最小,所以要在X变量相对应的边上加上权值,然后求最小费用最大流。

接下来,根据上面五个等式构图。

(1)每个等式为图中一个顶点,添加源点S和汇点T。

(2)如果一个等式中的数字为非负整数c,从源点S向该等式对应的顶点连接一条容量为c,权值为0的有向边;如果为负整数-c,从该等式对应的顶点向汇点T连接一条容量为c,权值为0的有向边。

(3)如果一个变量X[i]在第j个等式中出现为-X[i],在第k个等式中出现为+X[i],从顶点j向顶点k连接一条容量为INF,权值为V[i]的有向边。

(4)如果一个变量Y[i]在第j个等式中出现为-Y[i],在第k个等式中出现为+Y[i],从顶点j向顶点k连接一条容量为INF,权值为0的有向边。

构图以后,求从源点S到汇点T的最小费用最大流,费用值就是结果。

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <bitset>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define rb(a) scanf("%lf", &a)
#define rf(a) scanf("%f", &a)
#define pd(a) printf("%d\n", a)
#define plld(a) printf("%lld\n", a)
#define pc(a) printf("%c\n", a)
#define ps(a) printf("%s\n", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 1e5 + , INF = 0x7fffffff, LL_INF = 0x7fffffffffffffff;
int n, m, s, t;
int head[maxn], d[maxn], vis[maxn], nex[maxn], f[maxn], p[maxn], cnt;
int xu[maxn], flow, value; struct node
{
int u, v, w, c;
}Node[maxn]; void add_(int u, int v, int w, int c)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt].w = w;
Node[cnt].c = c;
nex[cnt] = head[u];
head[u] = cnt++;
} void add(int u, int v, int w, int c)
{
add_(u, v, w, c);
add_(v, u, -w, );
} int spfa()
{
for(int i = ; i < maxn; i ++) d[i] = INF;
deque<int> Q;
mem(vis, );
mem(p, -);
Q.push_front(s);
d[s] = ;
p[s] = , f[s] = INF;
while(!Q.empty())
{
int u = Q.front(); Q.pop_front();
vis[u] = ;
for(int i = head[u];i != -; i = nex[i])
{
int v = Node[i].v;
if(Node[i].c)
{
if(d[v] > d[u] + Node[i].w)
{
d[v] = d[u] + Node[i].w;
p[v] = i;
f[v] = min(f[u], Node[i].c);
if(!vis[v])
{
// cout << v << endl;
if(Q.empty()) Q.push_front(v);
else
{
if(d[v] < d[Q.front()]) Q.push_front(v);
else Q.push_back(v);
}
vis[v] = ;
}
}
}
}
}
if(p[t] == -) return ;
flow += f[t], value += f[t] * d[t];
// cout << value << endl;
for(int i = t; i != s; i = Node[p[i]].u)
{
Node[p[i]].c -= f[t];
Node[p[i] ^ ].c += f[t];
}
return ;
} void max_flow()
{
flow = value = ;
while(spfa());
pd(value);
} void init()
{
mem(head, -);
cnt = ;
} int main()
{
init();
int u, v, w;
rd(n), rd(m);
s = , t = n + ;
for(int i = ; i <= n; i++)
{
rd(xu[i]);
}
for(int i = ; i <= m; i++)
{
rd(u), rd(v), rd(w);
add(u, v + , w, INF);
}
for(int i = ; i <= n+; i++)
{
int tmp = xu[i] - xu[i - ];
if(tmp > ) add(s, i, , tmp);
else add(i, t, , -tmp);
if(i > ) add(i, i - , , INF);
}
max_flow(); return ;
}

志愿者招募 HYSBZ - 1061(公式建图费用流)的更多相关文章

  1. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

  2. 洛谷 P5331 - [SNOI2019]通信(CDQ 分治优化建图+费用流)

    题面传送门 首先熟悉网络流的同学应该能一眼看出此题的建模方法: 将每个点拆成两个点 \(in_i,out_i\),连一条 \(S\to in_i\),容量为 \(1\) 费用为 \(0\) 的边 连一 ...

  3. 【BZOJ-1570】BlueMary的旅行 分层建图 + 最大流

    1570: [JSOI2008]Blue Mary的旅行 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 388  Solved: 212[Submit ...

  4. BZOJ-1305 dance跳舞 建图+最大流+二分判定

    跟随YveH的脚步又做了道网络流...%%% 1305: [CQOI2009]dance跳舞 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 2119 S ...

  5. 2018.09.27 codeforces1045A. Last chance(线段树优化建图+最大流)

    传送门 看完题应该都知道是网络流了吧. 但是第二种武器直接建图会gg. 因此我们用线段树优化建图. 具体操作就是,对于这m个人先建一棵线段树,父亲向儿子连容量为inf的边,最后叶子结点向对应的人连容量 ...

  6. HDU3605: Escape-二进制优化建图-最大流

    目录 目录 思路: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 目录 题意:传送门  原题目描述在最下面.  \(n(n\leq 100000)\)个人\(m(m\leq 10) ...

  7. [BZOJ4205][FJ2015集训] 卡牌配对 [建图+最大流]

    题面 这是bzoj权限题,题面可以去下面的离线题库找 离线4205,只有题面,不能提交 思路 二分图匹配 这道题模型显然就是个二分图匹配嘛 那我们两两判断一下然后连边匹配.....就只有30分了 因为 ...

  8. HDU 3416 Marriage Match IV (最短路建图+最大流)

    (点击此处查看原题) 题目分析 题意:给出一个有n个结点,m条单向边的有向图,问从源点s到汇点t的不重合的最短路有多少条,所谓不重复,意思是任意两条最短路径都不共用一条边,而且任意两点之间的边只会用一 ...

  9. [HEOI2016/TJOI2016][bzoj4554] 游戏 [建图+最大流]

    题面 传送门 思路 看到棋盘摆放和棋子冲突,再加上这么小的数据范围,你能想到什么? 网络流棋盘模型啊! 就是 把源点连到每一行,每一列连到汇点,再在中间...... 等等,这道题每行不一定全部冲突?? ...

随机推荐

  1. java 接口实现防盗门功能

    Door: package locker; public abstract class Door { public abstract void open(); public abstract void ...

  2. windows 环境下 eclipse + maven + tomcat 的 hello world 创建和部署

    主要记录自己一个新手用 eclipse + maven + tomcat 搭建 hello world 的过程,以及遇到的问题.讲真都是自己通过百度和谷歌一步步搭建的项目,没问过高手,也没高手可问,由 ...

  3. asp.net mvc 自定义全局过滤器 验证用户是否登录

    一般具有用户模块的系统都需要对用户是否登录进行验证,如果用户登录了就可以继续操作,否则退回用户的登录页面 对于这样的需求我们可以通过自定义一个独立的方法来完成验证的操作,但是这样代码的重复率就大大提高 ...

  4. laravel门面和服务提供者使用

      关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel ...

  5. 项目中常用的MySQL 优化

    本文我们来谈谈项目中常用的MySQL优化方法,共19条,具体如下: 一.EXPLAIN 做MySQL优化,我们要善用EXPLAIN查看SQL执行计划. 下面来个简单的示例,标注(1.2.3.4.5)我 ...

  6. java学习之—栈

    /** * 栈 * Create by Administrator * 2018/6/11 0011 * 上午 10:20 **/ public class StackX { private int ...

  7. Session和Cookie介绍及常见httpcode

    Cookie和Session,及常见httpcode 1.cookie和session简介: cookie是放在客户端的键值对,用来识别用户信息的,主要包括:名字,值,过期时间,路径和域.路径与域一起 ...

  8. linux查看端口是否开放

    在讨论这个问题前,我们先来了解一下物理端口.逻辑端口.端口号等计算机概念. 端口相关的概念: 在网络技术中,端口(Port)包括逻辑端口和物理端口两种类型.物理端口指的是物理存在的端口,如ADSL M ...

  9. lombok 使用 Idea

    Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注解实现这一目的.import lombok.Getter;i ...

  10. pycharm 破解密码

    server选项里边输入 http://idea.imsxm.com/