志愿者招募 [NOI2008] [鬼畜网络流]
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
【样例说明】
招募3 名第一类志愿者和4 名第三类志愿者。
【数据规模和约定】
30%的数据中,1 ≤ N, M ≤ 10,1 ≤ Ai ≤ 10;
100%的数据中,1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均不超过2^31-1。
Solution
网络流的难点在于建模,此题的建模方法很鬼畜。
首先明确,这显然是一个最小费用最大流的题。
有一个源点S,汇点T,中间夹了n+1个点(对,就是n+1)
(α)首先,S->1和n+1->T分别连一条(INF,0)的边 ((x,y)表示容量x,代价y)
(β)然后对于i->i+1,连一条边为(INF-Ai,0)
(γ)在最后每一类志愿者,连一条Si->Ti+1(INF,Ci)的边
为什么要这样做?
我们一开始建的两条边(α)确保了到最后一定流量为INF (最大流特性)
然后再看剩下的边,会优先走(β),因为代价是0
但是由于减掉了Ai,意味着要保证满流必须走有代价的边(γ)
最后的答案就是(每次流量×代价和)的和了
Code
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define RG register int
#define rep(i,a,b) for(RG i=a;i<=b;i++)
#define per(i,a,b) for(RG i=a;i>=b;i--)
#define inf (1<<30)
#define maxn 1005
#define maxm 1000005
using namespace std;
int n,m,cnt=,S,T;
int ned[maxn],head[maxn],dis[maxn],vis[maxn],pre[maxn];
struct E{
int u,v,fl,cost,next;
}e[maxm<<];
inline int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} inline void add(int u,int v,int fl,int cost)
{
e[++cnt]=(E){u,v,fl,cost,head[u]},head[u]=cnt,swap(u,v);
e[++cnt]=(E){u,v,,-cost,head[u]},head[u]=cnt;
} int SPFA()
{
queue<int> que;
memset(dis,,sizeof(dis)),memset(pre,-,sizeof(pre)),memset(vis,,sizeof(vis));
que.push(S),dis[S]=;
RG u,v;
while(!que.empty())
{
u=que.front(),que.pop();vis[u]=;
for(RG i=head[u];i;i=e[i].next)
{
v=e[i].v;
if(e[i].fl>&&dis[v]>dis[u]+e[i].cost)
{
pre[v]=i;
dis[v]=dis[u]+e[i].cost;
if(!vis[v])
vis[v]=,que.push(v);
}
}
}
return pre[T]!=-;
} void MCMF()
{
int ans=;
while(SPFA())
{
RG now=T,fl=inf;
while(now!=S) fl=min(fl,e[pre[now]].fl),now=e[pre[now]].u;
ans+=dis[T]*fl;
now=T;
while(now!=S) e[pre[now]].fl-=fl,e[pre[now]^].fl+=fl,now=e[pre[now]].u; //bug
}
printf("%d",ans);
} int main()
{
n=read(),m=read(),S=,T=n+;
for(RG i=,tmp;i<=n;i++)
tmp=read(),add(i,i+,inf-tmp,);
for(RG i=,u,v,val;i<=m;i++)
u=read(),v=read(),val=read(),add(u,v+,inf,val);
add(S,,inf,),add(n+,T,inf,);
MCMF();
return ;
}
志愿者招募 [NOI2008] [鬼畜网络流]的更多相关文章
- 从[NOI2008志愿者招募]浅谈线性规划在网络流构图上的巧用
首先来看一下题..http://www.lydsy.com/JudgeOnline/problem.php?id=1061 1061: [Noi2008]志愿者招募 Description 申奥成功后 ...
- 网络流解线性规划问题 BZOJ1061: [Noi2008]志愿者招募
线性规划定义: 在给定有限的资源和竞争约束情况下,很多问题都可以表述为最大化或最小化某个目标.如果可以把目标指定为某些变量的线性函数,而且如果可以将资源约束指定为这些变量的等式或不等式,则得到了一个线 ...
- 【BZOJ 1061】 1061: [Noi2008]志愿者招募 (线性规划与网络流)**
1061: [Noi2008]志愿者招募 Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短 ...
- 线性规划||网络流(费用流):COGS 288. [NOI2008] 志愿者招募
[NOI2008] 志愿者招募 输入文件:employee.in 输出文件:employee.out 简单对比 时间限制:2 s 内存限制:512 MB [问题描述] 申奥成功后,布布经过 ...
- BZOJ 1061: [Noi2008]志愿者招募
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4064 Solved: 2476[Submit][Stat ...
- 【BZOJ】【1061】【NOI2008】志愿者招募
网络流/费用流 OrzOrzOrz,这题太神了不会捉. 题解:https://www.byvoid.com/blog/noi-2008-employee/ 这道题正确的解法是构造网络,求网络最小费用最 ...
- NOI2008 志愿者招募
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 1859 Solved: 1169[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3975 Solved: 2421[Submit][Stat ...
- [BZOJ1061][Noi2008]志愿者招募
[BZOJ1061][Noi2008]志愿者招募 试题描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿 ...
随机推荐
- mongodb 安装时错误
1.安装MongoDB进度条长时间不动 根据在网上搜的步骤安装mongoDB到这步,就基本上卡死不动,在网上查到的办法是死等,等了半个小时,但运气不好半个小时也不一定安装成功. 如果进行到这步,卡死在 ...
- JavaScript中this 详解
涵义 this 关键字是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 首先, this 总是返回一个对象,简单说,就是返回属性或方法“当前”所在的对象. this.p ...
- openresty用naxsi防xss、SQL注入
下载naxsi wget https://github.com/nbs-system/naxsi/archive/untagged-afabfc163946baa8036f.tar.gz tar zx ...
- 【CF809D】Hitchhiking in the Baltic States
题意: 给你n个区间[li,ri],让你选出从中一个子序列,然后在子序列的每个区间里都选择一个tj,满足t1<t2<...<tlent1<t2<...<tlen.最 ...
- 20165220 2017-2018-2《Java程序设计》课程总结
每周作业链接汇总: 20165220 我期望的师生关系 20165220 学习基础和C语言基础调查 20165220 Linux安装及学习 20165220 第一周学习总结 20165220 第二周学 ...
- POJ 2631 Roads in the North (模板题)(树的直径)
<题目链接> 题目大意:求一颗带权树上任意两点的最远路径长度. 解题分析: 裸的树的直径,可由树形DP和DFS.BFS求解,下面介绍的是BFS解法. 在树上跑两遍BFS即可,第一遍BFS以 ...
- POJ 3237 Tree 【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一棵树,该树带有边权,现在对该树进行三种操作: 一:改变指定编号边的边权: 二:对树上指定路径的边权全部取反: 三:查询树上指定路径的最大边权值. 解题分析: ...
- anaconda源配置
1. 生成配置文件 第一次运行 conda config命令时,将会在用户的home目录创建该文件..condarc配置文件,是一种可选的(optional)运行期配置文件,其默认情况下是不存在的. ...
- 在思科路由器上配置AAA认证
1.实验拓扑 网络情况 PC-A PING PC-B PC-A PING PC-C PC-B PING PC-C 2.R1的配置 a.console线 R1(config)#username admi ...
- 自定义Map.Entry的Comperator实现字符频率降序排序
leetCode (#451,middle) java实现 class Solution { public String frequencySort(String s) { Map<Charac ...