正题
AC链接:
https://www.luogu.org/record/show?rid=7949532
大意
有n个月,每个月商品价格di,需求量Ui。有容量为S的仓库,一个商品汇存一个月要m。求最低成本
解题思路
首先是月份做为点,成本作为费用,需求作为容量。
刚开始想的是专门做一个点作为仓库,后来发现其实可以直接向下连边。
然后就是这样构图:
然后求费用流就好了
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct line{int to,w,c,next;
}a[2001];
int tot,n,m,s,t,f[601],ls[601],tail,answer;
int state[601],x,y,w,c,ans,head,pre[601],S;
bool v[601];
void addl(int x,int y,int w,int c)
{a[++tot].to=y;a[tot].w=w;a[tot].c=c;a[tot].next=ls[x];ls[x]=tot;a[++tot].to=x;a[tot].w=0;a[tot].c=-c;a[tot].next=ls[y];ls[y]=tot;
}
bool spfa()
{memset(f,127/3,sizeof(f));memset(v,0,sizeof(v));head=0;tail=1;v[s]=true;state[1]=s;f[s]=0;while (head!=tail){head=head%500+1;int x=state[head];for (int q=ls[x];q;q=a[q].next){int y=a[q].to;if (a[q].w&&f[x]+a[q].c<f[y]){f[y]=f[x]+a[q].c;pre[y]=q;if (!v[y]){v[y]=true;tail=tail%500+1;state[tail]=y;}}}v[x]=false;}if (f[t]>=707406378) return 0;else return 1;
}
void upway()
{int k=2147483647,now=t;while (now!=s){k=min(k,a[pre[now]].w);now=a[pre[now]^1].to;}ans+=f[t]*k;now=t;answer+=k;while (now!=s){a[pre[now]].w-=k;a[pre[now]^1].w+=k;now=a[pre[now]^1].to;}
}
int main()
{tot=1;scanf("%d%d%d",&n,&m,&S);s=n+1;t=n+2;for (int i=1;i<=n;i++)scanf("%d",&x),addl(i,t,x,0);//完成订单for (int i=1;i<=n;i++)scanf("%d",&x),addl(s,i,1e9,x);//进货for (int i=1;i<n;i++)addl(i,i+1,S,m);//存while (spfa()){upway();}printf("%d",ans);
}