【BZOJ2424】[HAOI2010]订货(费用流)

【BZOJ2424】[HAOI2010]订货(费用流)

题面

BZOJ
洛谷

题解

傻逼费用流吧、、、
一开始理解错意思了,仓库大小为\(m\)的含义是留到下个月最多为\(m\),而不是任意时刻的容量不能超过\(m\)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MAX 5000
#define MAXL 50000
#define inf 1000000000
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
struct Line{int v,next,w,fy;}e[MAXL];
int h[MAX],cnt=2;
inline void Add(int u,int v,int w,int fy)
{
    e[cnt]=(Line){v,h[u],w,fy};h[u]=cnt++;
    e[cnt]=(Line){u,h[v],0,-fy};h[v]=cnt++;
}
int S,T,Cost,Flow,dis[MAX],pv[MAX],pe[MAX];
bool vis[MAX];
bool SPFA()
{
    memset(dis,63,sizeof(dis));dis[S]=0;
    queue<int> Q;Q.push(S);vis[S]=true;
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();
        for(int i=h[u];i;i=e[i].next)
        {
            int v=e[i].v;
            if(e[i].w&&dis[v]>dis[u]+e[i].fy)
            {
                dis[v]=dis[u]+e[i].fy;pe[v]=i;pv[v]=u;
                if(!vis[v])vis[v]=true,Q.push(v);
            }
        }
        vis[u]=false;
    }
    if(dis[T]>1e9)return false;
    int flow=1e9;
    for(int i=T;i!=S;i=pv[i])flow=min(flow,e[pe[i]].w);
    for(int i=T;i!=S;i=pv[i])e[pe[i]].w-=flow,e[pe[i]^1].w+=flow;
    Cost+=flow*dis[T];Flow+=flow;
    return true;
}
int n,m,s,tot;
int main()
{
	n=read();m=read();s=read();S=0;T=n+1;
	for(int i=1;i<=n;++i)Add(i,T,read(),0);
	for(int i=1;i<=n;++i)Add(S,i,inf,read());
	for(int i=1;i<n;++i)Add(i,i+1,s,m);
	while(SPFA());
	printf("%d\n",Cost);
	return 0;		
}
posted @ 2018-10-29 22:48  小蒟蒻yyb  阅读(181)  评论(0编辑  收藏  举报