[haoi2010]订货 最小费用流

时间:2023-03-09 15:06:51
[haoi2010]订货 最小费用流

这道题oj上的标签是动态规划,但我想不出来动态规划怎么搞,空间不爆,时间也要爆的;

好的,不扯淡,此题正常做法是最小费用流;

这道题我写了两遍,为什么呢?原因是第一次写的时候,不会写费用流,又恰好没带书,所以搁置了;

第二次又写到这道题了,有点生气,一鼓作气学了费用流,紧跟着敲了这道题;

也算一道费用流模板吧;

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
using namespace std;
const int maxn=;
const int inf=;
const int S=,T=+;
struct node{
int x,y,next,flow,v,re;
}e[maxn];
int linkk[maxn],len=,n,m,s,u[maxn],c[maxn];
void insert(int x,int y,int flow,int v){
e[++len].x=x;
e[len].y=y;
e[len].v=v;
e[len].flow=flow;
e[len].next=linkk[x];
e[len].re=len+;
linkk[x]=len;
e[++len].x=y;
e[len].y=x;
e[len].flow=;
e[len].v=v;
e[len].next=linkk[y];
e[len].re=len-;
linkk[y]=len;
}
void init(){
scanf("%d%d%d",&n,&m,&s);
for(int i=;i<=n;i++)scanf("%d",&u[i]);
for(int i=;i<=n;i++)scanf("%d",&c[i]);
for(int i=;i<=n;i++){
insert(S,i,inf,c[i]);insert(i,T,u[i],);
}
for(int i=;i<n;i++)insert(i,i+,s,m);
}
int vis[maxn],d[maxn],q[maxn*maxn],head=,tail=,pre[maxn],ans=,cap[maxn],t[maxn];
bool SPFA(){
for(int i=S;i<=T;i++)d[i]=inf<<;
memset(vis,,sizeof(vis));
head=,tail=;
q[++tail]=S;d[S]=;
while(++head<=tail){
int x=q[head];
vis[x]=;
for(int i=linkk[x];i;i=e[i].next){
if(e[i].flow&&d[e[i].y]>d[x]+e[i].v){
d[e[i].y]=d[x]+e[i].v;
cap[e[i].y]=e[i].flow;
t[e[i].y]=i;
pre[e[i].y]=x;
if(!vis[e[i].y]){
vis[e[i].y]=;
q[++tail]=e[i].y;
}
}
}
}
if(d[T]==inf<<)return ;
int flow=inf;
for(int i=T;i!=S;i=pre[i])flow=min(flow,cap[i]);
for(int i=T;i!=S;i=pre[i]){
e[t[i]].flow-=flow;
e[e[t[i]].re].flow+=flow;
ans+=e[t[i]].v*flow;
}
return ;
}
void work(){
ans=;
while(SPFA());
cout<<ans<<endl;
}
int main(){
init();
work();
}