[SDOI2011][bzoj2245] 工作分配 [费用流]
题面
思路
数据范围n,m<=250
分配任务问题
这是典型的“看到数据范围就知道算法”类型
而且我们发现我们要保证一定产出的情况下最小化花费
这句话等价于保证一定流量的情况下最小化费用
所以先确定算法:最小费用最大流
再观察一下,我们发现这道题的费用和人唯一相关,而且人和物品之间的关系是独立的
因此我们建立一个网络流图,其中包含S,T,人点和物品点
对于每个物品i,我们连边(i,T),费用0,流量为$C_i$
对于一个人i可以操作物品j,我们连边(i,j),费用0,流量inf
接下来的问题就是处理人的费用了
我们发现这道题的费用是分段处理的
看到分段,第一想法就是把人拆点,但是这样势必会大大增加冗余边数,拖慢程序速度
因此我们考虑不拆点来做
观察发现,这道题分段中保证$W_{i,j}$递增
也就是说,如果有一坨重边,我们的算法会先跑代表靠前的分段的边
这引导我们往重边方向上想
对于一个点i,我们把每个长度为l,段中费用为cost的分段,连一条边(S,i),费用cost,流量l
因为每个点最多六段,所以这个算法的边数很少,跑得过
最后只要一步(S,T)费用流,输出总费用就可以了
Code:
这题卡常数啊......
而且我的zkw费用流被卡了过不了,洛谷评测机又不稳定,一会TLE一会RE的......
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 1e9
#define ll long long
using namespace std;
inline ll read(){
ll re=0,flag=1;char ch=getchar();
while(ch>'9'||ch<'0'){
if(ch=='-') flag=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
ll first[5010],dis[5010],vis[5010],n,m,cnt=-1,ans;
struct edge{
ll to,next,w,cap;
}a[600010];
inline void add(ll u,ll v,ll w,ll cap){
a[++cnt]=(edge){v,first[u],w,cap};first[u]=cnt;
a[++cnt]=(edge){u,first[v],-w,0};first[v]=cnt;
}
ll q[1000010];
ll limit[5010],pre[5010];
bool Spfa(int s,int t){
ll head=0,tail=1,i,u,v,w;
memset(dis,-1,sizeof(dis));memset(vis,0,sizeof(vis));
memset(limit,0,sizeof(limit));memset(pre,-1,sizeof(pre));
q[0]=s;dis[s]=0;vis[s]=1;limit[s]=inf;
while(head<tail){
u=q[head++];vis[u]=0;
for(i=first[u];~i;i=a[i].next){
v=a[i].to;w=a[i].w;
if(a[i].cap&&((dis[v]==-1)||(dis[v]>dis[u]+w))){
dis[v]=dis[u]+w;pre[v]=i;
limit[v]=_min(limit[u],a[i].cap);
if(!vis[v]) q[tail++]=v,vis[v]=1;
}
}
}
return ~dis[t];
}
int mcmf(int s,int t){
int re=0,u;
while(Spfa(s,t)){
re+=limit[t];
for(u=t;~pre[u];u=a[pre[u]^1].to){
a[pre[u]].cap-=limit[t];a[pre[u]^1].cap+=limit[t];
ans+=limit[t]*a[pre[u]].w;
}
}
return re;
}
int main(){
memset(first,-1,sizeof(first));
m=read();n=read();ll i,j,t1,t2[10],t3;
for(i=1;i<=n;i++) t1=read(),add(0,i,0,t1);
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
t1=read();
if(t1) add(j,n+i,0,inf);
}
}
for(i=1;i<=m;i++){
t1=read();t2[0]=0;
for(j=1;j<=t1;j++) t2[j]=read();
for(j=0;j<t1;j++){//分段建重边
t3=read();
add(n+i,n+m+1,t3,t2[j+1]-t2[j]);
}
t3=read();add(n+i,n+m+1,t3,inf);
}
mcmf(0,n+m+1);
cout<<ans<<endl;
}
[SDOI2011][bzoj2245] 工作分配 [费用流]的更多相关文章
- 【bzoj2245】[SDOI2011]工作安排 费用流
题目描述 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被编号为1~m员工能够制造的产品种类有所区别.一件产品必须完整地由 ...
- BZOJ 2245: [SDOI2011]工作安排( 费用流 )
费用流模板题..限制一下不同愤怒值的工作数就可以了. ------------------------------------------------------------------------- ...
- P2488 [SDOI2011]工作安排 费用流
\(\color{#0066ff}{ 题目描述 }\) 你的任务是制定出一个产品的分配方案,使得订单条件被满足,并且所有员工的愤怒值之和最小.由于我们并不想使用Special Judge,也为了使选手 ...
- BZOJ 2245 SDOI 2011 工作安排 费用流
题目大意:有一些商品须要被制造.有一些员工.每个员工会做一些物品,然而这些员工做物品越多,他们的愤慨值越大,这满足一个分段函数.给出哪些员工能够做哪些东西,给出这些分段函数,求最小的愤慨值以满足须要被 ...
- [bzoj2245][SDOI2011]工作安排——费用流
题目大意: 传送门 题解: 很容易建模,把每一个工作人员拆成两个点,由第一个点向第二个点连S+1条边即可. 这水题没什么难度,主要是longlong卡的丧心病狂... 代码 #include < ...
- 【BZOJ2245】[SDOI2011]工作安排 拆边费用流
[BZOJ2245][SDOI2011]工作安排 Description 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被 ...
- 【BZOJ2245】[SDOI2011]工作安排(费用流)
[BZOJ2245][SDOI2011]工作安排(费用流) 题面 BZOJ 洛谷 题解 裸的费用流吧. 不需要拆点,只需要连边就好了,保证了\(W_j<W_{j+1}\). #include&l ...
- [bzoj2245][SDOI2011]工作安排(费用流)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2245 分析: 要注意到题目下面说的w是单增的 明显的费用流: 弄个源点S,汇点T S连 ...
- 【TYVJ】1982 武器分配(费用流)
http://tyvj.cn/Problem_Show.aspx?id=1982 一眼题.. 源向每个人连容量为1,费用为0的边. 每个人向一个中转节点na连容量1,费用0的边(你也可以不连,直接连后 ...
随机推荐
- Java 虚拟机枚举 GC Roots 解析
JVM 堆内存模型镇楼. 读<深入理解 Java 虚拟机>第三章GC算法,关于 GC Roots 枚举的段落没说透彻,理解上遇到困惑.因此对这点进行扩展并记录,发现国内各种博客写来写去都是 ...
- C#装箱与拆箱的研究
在对这个问题展开讨论之前,我们不妨先来问这么几个问题,以系统的了解我们今天要探究的主题. 观者也许曾无数次的使用过诸如System.Console类或.NET类库中那些品种繁多的类.那么,我想问的是它 ...
- Oracle 数据库、实例、表空间、用户、数据库对象
Oracle是一种数据库管理系统,是一种关系型的数据库管理系统.通常情况了我们称的“数据库”,包含了物理数据.数据库管理系统.内存.操作系统进程的组合体,就是指这里所说的数据库管理系统. 完整的Ora ...
- SPOJ2713GSS4 - Can you answer these queries IV(线段树)
题意 Sol 讲过无数次了..很显然,一个$10^12$的数开方不超过$8$次后就会变为$1$ 因此直接暴力更改即可,维护一下这段区间是否被全改为了$1$ 双倍经验:https://www.luogu ...
- ubuntu crontab设置定时任务
ubuntu 设置定时任务 crontab -l #查看详情crontab -e #设置定时任务 * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用* ...
- 以太坊国内节点大全(ropsten)
admin.addPeer('enode://2d1e1f1242c3b54ea56046f74f15943f47ab410e3c0b82bffb501793ebb19e147f8f0e63d01c2 ...
- 动态规划:HDU1789-Doing Homework again
Doing Homework again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- 动态规划:HDU1069-Monkey and Banana
Monkey and Banana Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 菜鸟学Linux - Hard Link与Symbolic Link
在学习Hard Link与Symbolic Link之前,需要大概了解一下inode与data block.在Linux的文件系统中,一个文件对应一个inode与若干个data block.inode ...
- B树、B-树、B+树、B*树之间的关系
https://blog.csdn.net/u013411246/article/details/81088914