【BZOJ1061】【codevs1803】志愿者招募,神奇建图费用流
传送门1
传送门2
写在前面:第一次写成功的费用流是个神奇数学建模题……
思路:摘自http://www.ithao123.cn/content-4207689.html,感觉这个要比列不等式+松弛操作的说法更加明白简单
设每个时间i都需要有至少Ai个志愿者,设每种志愿者i使用了xi个,那么我们对于每个时间点都可以列出一个不等式:x1+x2+x3+…+xn>=Ai(其中如果第i类志愿者不能在该区间工作则xi固定为0)。
最后要求最小化w1*x1+w2*x2+x3*x3+…+wn*xn(其中wi是第i种志愿者的单位价格)。
这正是一个线性规划的问题。
那么我们是否可以转化为网络流来求解呢?
当然是可以哒~
现在我们将每个点的Ai取反,变成-Ai,这样他就成了一个“坑”了(相对于y=0而言),我们从源点S给最左边的时间点引流,流的大小为U(U为大整数),然后每个时间点i向时间点i+1建边(i,i+1,U-Ai,0),最后设汇点为最右端的时间点。
现在,如果所有时间点的Ai都为0,那么显然,汇点的流量恰好等于U。
问题来了,现在我们有的Ai不等于0了,那么显然源点到汇点的流量被这些“坑”所截断了,怎么解决这一个问题?
假设志愿者工作的时间为【Li,Ri】,且该种志愿者单位花费为Ci,则我们建边(Li,Ri+1,INF,Ci),表示我们雇佣了一些志愿者“填坑”来了,如果雇佣了xi个志愿者,则说明将该区间内的所有“坑”的深度填掉了xi(当然可能有的坑在“填坑”行动后高于y=0,那也无所谓了嘛,多多益善~)。
那么现在是不是看起来思路有一点清晰了?
于是志愿者的作用就是一个人可以填一个区间的“坑”(好厉害!),然后需要每种志愿者选择一些使得花费最小的情况下填掉所有的“坑”,就是这样~
最后就是让费用流帮我们选择志愿者的时候了~
于是我们按照上面的方法跑完一遍最小费用最大流,如果流量等于U,则说明满流(志愿者们成功填掉了所有的坑,同志们辛苦了~),此时的记录的cost就是最小值(cost为算法记录的最小费用)。如果流量不等于U则无解。
这时我们又收获了一种费用流的模型:初始给一道大流,然后将有至少覆盖次数限制的点(边)的权值取反变成“坑”,最后区间覆盖就等于“填坑”,只要最后的流量等于大流的流量,就有解。
注意:
1.建图不要想当然,一定要遵从流量守恒等原则,最好在纸上画画写写,并手动跑一遍
2.小心int溢出,这个好坑的
代码:
#include"bits/stdc++.h"
#define Maxn 0x7fffffff
#define LL long long
using namespace std;
int tot=1,s,t,n,m,up[20010];
bool flag[20010];
LL ans,dis[20010];
int person[1010],start[10010],end[10010],c[10010],first[20010];
struct os
{int fa,son,next;LL limit,cost;
}a[100000];
queue<int> q;
void add(LL x,LL y,LL z,LL co)
{a[++tot].fa=x;a[tot].son=y;a[tot].limit=z;a[tot].cost=co;a[tot].next=first[x];first[x]=tot;
}
bool spfa()
{memset(dis,127,sizeof(dis));memset(up,0,sizeof(up));dis[s]=0;flag[s]=1;q.push(s);LL k;while (!q.empty()){k=q.front();for (LL i=first[k];i;i=a[i].next)if (a[i].limit&&dis[a[i].son]>dis[k]+a[i].cost){dis[a[i].son]=dis[k]+a[i].cost;up[a[i].son]=i;if (!flag[a[i].son]) flag[a[i].son]=1,q.push(a[i].son);}q.pop();flag[k]=0;}if (dis[t]<0x7fffff) return 1;else return 0;
}
LL flow()
{LL ans=0,minn=0x7fffffff;for (int i=up[t];i;i=up[a[i].fa])minn=min(minn,a[i].limit);if (minn==Maxn) return 0;for (int i=up[t];i;i=up[a[i].fa])ans+=minn*a[i].cost,a[i].limit-=minn,a[i^1].limit+=minn;return ans;
}
main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)scanf("%d",&person[i]);for (int i=1;i<=m;i++)scanf("%d%d%d",&start[i],&end[i],&c[i]);s=n+2;t=n+1;add(s,1,Maxn,0);add(1,s,0,0);for (int i=1;i<=n;i++)add(i,i+1,Maxn-person[i],0),add(i+1,i,Maxn,0);for (int i=1;i<=m;i++)add(start[i],end[i]+1,Maxn,c[i]),add(end[i]+1,start[i],0,-c[i]);while (spfa()) ans+=flow();printf("%lld",ans);
}
【BZOJ1061】【codevs1803】志愿者招募,神奇建图费用流相关推荐
- [NOI2008] 志愿者招募(线性规划-对偶问题-费用流)
problem luogu-P3980 solution 志愿者连续工作 [ s i , t i ] [s_i,t_i] [si,ti] 天,我们可以提炼出网络流二十四题中<最长k可重区间集 ...
- [BZOJ1061][Noi2008]志愿者招募
[BZOJ1061][Noi2008]志愿者招募 试题描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿 ...
- 【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MB Submit: 5291 Solved: 3173 [Submit][St ...
- [Bzoj1061][Noi2008]志愿者招募(费用流)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1061 一开始疯狂想dp,然后队友走过来瞄一眼就告诉我像费用流,菜的真实,jpg. 一种比 ...
- [BZOJ1061] [NOI2008] 志愿者招募 - 最小费用最大流
大部分内容转自: BYVOID - NOI2008 志愿者招募 如果讲道理的话,就是说我们抽象一下这个模型--然后每条费用边就是连接起始日期和结束日期的边,也就是说这条边上的流量增加1,就要增加一个 ...
- [bzoj1061] [NOI2008]志愿者招募
Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完 ...
- BZOJ1061 [NOI2008]志愿者招募
Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能 ...
- BZOJ1061: [Noi2008]志愿者招募
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1061 1061: [Noi2008]志愿者招募 Time Limit: 20 Sec M ...
- ZZULIOJ 2131 Can Win【思维建图+最大流】
2131: Can Win Time Limit: 1 Sec Memory Limit: 128 MB Submit: 479 Solved: 61 SubmitStatusWeb Board ...
最新文章
- MicroProfile 1.2新增功能介绍
- 树莓派3b与散热风扇
- 全球及中国胶原蛋白肠衣行业深度分析及投资战略规划报告2022-2028年版
- 树莓派hdmi输出没声音_树莓派 4 开箱记
- c语言让电脑发出滴滴声代码,centos命令行控制电脑发出滴滴声——使用beep把警告变为music...
- 1、绪论初识机器学习
- JAVA进阶开发之(二维数组)
- 奇偶数判断(信息学奥赛一本通-T1041)
- 复数四则运算 (15 分)
- 记录一次java.lang.ClassCastException的java类型转换异常解决方案-附最终解决方案
- python的隐藏功能分享_【图片】分享一段功能非常简陋的python代码实现下载free种【pt吧】_百度贴吧...
- flow-shop调度问题、job shop调度问题、open shop调度问题 是什么 区别
- urho3D 运动逆解Inverse Kinematics
- 每日一佳——Information-Theoretic Metric Learning(Jason V. Davis et al. ,ICML,2007)
- 什么是fail safe IO
- oracle daul是什么意思,Oracle中的dual表到底是干什么的
- android上传单个或多个文件
- 机器学习中常见的评估方法
- 中科曙光新型算力,构建数字设施大动脉
- 2021年高压电工及高压电工模拟考试题
热门文章
- 技术谈 | SDN 和 NFV 之间的爱与恨
- 【Python3网络爬虫开发实战】1.6.2-Tornado的安装
- android用java写文本框_Android 自动完成文本框的实例
- oracle10 ins tcx,安装Oracle10g遭遇ins_ctx.mk问题-Oracle
- The tempotron: a neuron that learns spike timing–based decisions 事件驱动
- poj1258 Agri-Net 最小生成树Kruskal、Prim
- qt根据散点图拟合曲线_R可视化 | 散点图系列(1)
- dll可以在linux下使用吗_Linux下使用rm删除文件,并排除指定文件
- 例子---JS无缝轮播图
- mybatis case when_MyBatis 几种通用的写法