BZOJ.1061.[NOI2008]志愿者招募(线性规划 对偶原理 单纯形 / 费用流SPFA)
线性规划
用\(A_{ij}=0/1\)表示第\(i\)天\(j\)类志愿者能否被招募,\(x_i\)为\(i\)类志愿者招募了多少人,\(need_i\)表示第\(i\)天需要多少人,\(C_i\)表示\(i\)类招募志愿者的花费。
那么我们需要$$最小化\ Cx\s.t.\ Ax\geq need\x\geq 0$$
(s.t.:subject to,使得满足)
这是一个最小化线性规划,而不是标准型的最大化线性规划。根据对偶原理(见这儿),我们把它变成:$$最大化\ x*need\s.t.\ xA\leq C\x\geq 0$$
用非矩阵形式直观地写:$$最小化\ \sum_{i=1}mC_ix_i\s.t. \sum_{i=1}nA_{ij}x_j\geq need_i\ ,\ j=1,2,\ldots,m\x_j\geq 0$$
利用对偶原理,转化为:$$最大化\ \sum_{i=1}nneed_ix_i\s.t. \sum_{i=1}nA_{ij}x_i\leq C_j\ ,\ j=1,2,\ldots,m\x_i\geq 0$$
这样就可以直接用单纯形做了。因为\(C_i\)非负,所以一定有解,不需要Init()。
还有一个问题,线性规划的解是否可能非整数?
我不知道为什么有这么个...常识定理?
线性规划的问题的最优解为整数的一个必要条件是它的任意一个子方阵的行列式为\(-1, 0, 1\)。
反正这有\(Candy?\)的结论,我就记住吧。。
下面有洛谷上题解的证明,证明本题方阵的任意一个子方阵的行列式为\(-1, 0或1\)。(全单位模矩阵)
另外加强版,单纯形应该不对,然而数据比较水。

Proof:

//79668kb 1172ms(果然还是比费用流慢多了)
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define eps 1e-8
const int N=1005,M=10005;
int n,m;
double A[M][N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Pivot(int r,int c)
{
double t=A[r][c]; A[r][c]=1;
for(int i=0; i<=n; ++i) A[r][i]/=t;
for(int i=0; i<=m; ++i)
if(i!=r && fabs(A[i][c])>eps)
{
double t=A[i][c]; A[i][c]=0;
for(int j=0; j<=n; ++j) A[i][j]-=t*A[r][j];
}
}
void Simplex()
{
for(int r,c; ; )
{
r=c=0;
for(int i=1; i<=n; ++i)
if(A[0][i]>eps) {c=i; break;}
if(!c) break;
double mn=1e15;
for(int i=1; i<=m; ++i)
if(A[i][c]>eps && mn>A[i][0]/A[i][c]) r=i, mn=A[i][0]/A[i][c];
if(!r) break;
Pivot(r,c);
}
}
int main()
{
n=read(), m=read();
for(int i=1; i<=n; ++i) A[0][i]=read();
for(int i=1,l,r; i<=m; ++i)
{
l=read(), r=read(), A[i][0]=read();
for(int j=l; j<=r; ++j) A[i][j]=1;
}
Simplex(), printf("%.0lf\n",-A[0][0]);
return 0;
}
费用流
用\(u\rightarrow v\ (f,\ c)\)表示一条\(u\rightarrow v\)容量为\(f\),花费为\(c\)的边。
对于每一类志愿者,连边\(l_i\rightarrow r_i+1\ (INF,\ cost_i)\);
每相邻的两天,连边\(i\rightarrow i+1\ (INF-need_i,\ 0)\);
对于源点汇点,连边\(S\rightarrow 1\ (INF,\ 0)\)、\(n+1\rightarrow T\ (INF,\ 0)\)。
因为一定存在可行解,所以最后流量一定可以扩充成INF。
对于每两天之间的连边会优先流,因为花费为0,而不经过这条边但覆盖这一段的边的流量之和一定不小于\(need_i\)。即缺少的流量会通过带权边补成INF,且能保证方案最优。
嗯...好吧我不会写费用流了。。
//1592kb 164ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=1007,M=11007<<1,INF=0x3f3f3f3f;
int src,des,n,m,Enum,H[N],nxt[M],fr[M],to[M],cap[M],cost[M],pre[N],dis[N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v,int w,int c)
{
fr[++Enum]=u, to[Enum]=v, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w, cost[Enum]=c;
fr[++Enum]=v, to[Enum]=u, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0, cost[Enum]=-c;
}
bool SPFA()
{
static std::queue<int> q;
static bool inq[N];
memset(dis,0x3f,sizeof dis);
dis[src]=0, q.push(src);
while(!q.empty())
{
int x=q.front(); q.pop();
inq[x]=0;
for(int v,i=H[x]; i; i=nxt[i])
if(cap[i] && dis[v=to[i]]>dis[x]+cost[i])
{
dis[v]=dis[x]+cost[i], pre[v]=i;
if(!inq[v]) inq[v]=1, q.push(v);
}
}
return dis[des]<INF;
}
int MCMF()
{
int res=0, mn=INF;
for(int i=des; i!=src; i=fr[pre[i]])
mn=std::min(mn,cap[pre[i]]);
for(int i=des,v=pre[i]; i!=src; i=fr[v],v=pre[i])
res+=mn*cost[v], cap[v]-=mn, cap[v^1]+=mn;
return res;
}
int main()
{
n=read(), m=read(), Enum=1, src=1, des=n+2;
for(int i=1; i<=n; ++i) AddEdge(i,i+1,INF-read(),0);
for(int i=1,l,r; i<=m; ++i) l=read(),r=read(),AddEdge(l,r+1,INF,read());
AddEdge(n+1,des,INF,0);
int res=0;
while(SPFA()) res+=MCMF();
printf("%d\n",res);
return 0;
}
BZOJ.1061.[NOI2008]志愿者招募(线性规划 对偶原理 单纯形 / 费用流SPFA)的更多相关文章
- BZOJ 1061: [Noi2008]志愿者招募【单纯形裸题】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4813 Solved: 2877[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3975 Solved: 2421[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记看另一篇吧】
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3975 Solved: 2421[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4064 Solved: 2476[Submit][Stat ...
- BZOJ 1061: [Noi2008]志愿者招募 费用流
1061: [Noi2008]志愿者招募 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1061 Description 申奥成功后,布布 ...
- 【刷题】BZOJ 1061 [Noi2008]志愿者招募
Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完 ...
- BZOJ 1061: [Noi2008]志愿者招募(线性规划与网络流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1061 题意: 思路: 直接放上大神的建模过程!!!(https://www.byvoid.com/z ...
- BZOJ 1061 [Noi2008]志愿者招募(费用流)
题目描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i ...
- bzoj 1061 [Noi2008]志愿者招募(数学模型,MCMF)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1061 [题意] 雇人满足每天至少需要的人数. [思路一] Byvoid的题解 clic ...
随机推荐
- Spring RedisTemplate操作-xml配置(1)
网上没能找到全的spring redistemplate操作例子,故特意化了点时间做了接口调用练习,基本包含了所有redistemplate方法. 该操作例子是个系列,该片为spring xml配置, ...
- ASP.NET MVC学习笔记-----ControllerFactory
上面这张图是asp.net mvc的工作流程图,我们可以看到当一个http请求来临时,首先需要经过路由系统,路由系统从中获取一些路由信息,然后ControllerFactory根据所得到的路由信息生成 ...
- Jquery自定义滚动条插件
下载地址:http://files.cnblogs.com/files/LoveOrHate/jquery.nicescroll.min.js <script src="jquery. ...
- javascript的单例/单体模式(Singleton)
首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点:1,该类只有一个实例2,该类自行创建该实例(在该类内部创建自身的实例对象)3,向整个系统公开这个实例接口 Java中大概是这 ...
- 【CodeForces】925 C.Big Secret 异或
[题目]C.Big Secret [题意]给定数组b,求重排列b数组使其前缀异或和数组a单调递增.\(n \leq 10^5,1 \leq b_i \leq 2^{60}\). [算法]异或 为了拆位 ...
- 1、Saltstack简介及安装配置
1.Saltstack简介 Saltstack是基于Python开发的一套C/S架构,具备Puppet.Ansible功能于一身的配置管理工具,功能十分强大,各模块融合度及复用性极高:使用号称世界上最 ...
- Dream------Hbase--0.94版本和0.98/1.X版本api变动
Dream------Hbase--0.94版本和0.98/1.X版本api变动 网上好多说getQualifier.getValue.getRow被..Array代替了,其实并不是的. 1. Int ...
- linux压缩日志并删除原始文件
下面的脚本可以压缩日志并删除原始文件 #!/bin/bash yesterday=`date -d '1days ago' +%Y_%m_%d` cd $ find . -name "*$y ...
- Mycat 配置及优化【转】
前言 Mycat 是一个数据库分库分表中间件 MyCAT 是作为通用代理设计的,后端是以 Mysql协议 和 JDBC 的方式连接数据库,可以支持 Oracle.DB2.SQL Server . mo ...
- Java 基本语法---Java数组
Java 基本语法---Java数组 0. 概述 数组:相同类型的数据 按照顺序 组成的一种 引用数据类型 . 数据类型:基本数据类型 + 引用数据类型: 引用数据类型:类 + 接口 + 数组 : 一 ...