1 条题解
-
0
自动搬运
来自洛谷,原作者为

徐致远
**搬运于
2025-08-24 21:55:35,当前版本为作者最后更新于2019-03-18 12:38:12,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
好经典的模型。
题解
乍一看就是一个二分图。
但是要求很明显要求最小费用最大流。
考虑如何建模。
由于每一个仓库只能流出定量的货物,但是又不能把每一个仓库看做源。
所以把所有货物都连到同一个源上,连到第个仓库的边嘚的容量为,费用为。
每一家零售店又都连到一个汇上,从第家零售店连出的边的容量为,费用为。
中间从仓库到零售店的边就按照题目里的说的那样连,容量为。

然后直接跑最小费用最大流就好了。
代码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=210,maxm=20205,inf=0x3F3F3F3F; int m,n,S,T,tot,lnk[maxn],son[maxm],nxt[maxm],w[maxm],cap[maxm],que[maxn],lst[maxn],pre[maxn],dist[maxn],flow[maxn],ans;bool vis[maxn]; inline int read() { int ret=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();} while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();} return ret*f; } inline void add_e(int x,int y,int z,int c){tot++;son[tot]=y;w[tot]=z;cap[tot]=c;nxt[tot]=lnk[x];lnk[x]=tot;} inline void MinCostMaxFlow(int flg) { while(true) { if(flg==1) memset(dist,63,sizeof(dist)); else memset(dist,192,sizeof(dist)); memset(flow,63,sizeof(flow)); int hed=0,til=1; que[1]=S;dist[S]=0;vis[S]=true;pre[T]=0; while(hed!=til) { hed=(hed+1)%maxn;vis[que[hed]]=false; for(int i=lnk[que[hed]];i;i=nxt[i]) { if(cap[i]&&((flg==1&&dist[que[hed]]+w[i]<dist[son[i]])||(flg==-1&&dist[que[hed]]+w[i]>dist[son[i]]))) { dist[son[i]]=dist[que[hed]]+w[i]; pre[son[i]]=que[hed]; lst[son[i]]=i; flow[son[i]]=min(flow[que[hed]],cap[i]); if(!vis[son[i]]) { vis[son[i]]=true; til=(til+1)%maxn; que[til]=son[i]; } } } } if(pre[T]==0) return; ans+=flow[T]*dist[T]; int p=T; while(p!=S) { cap[lst[p]]-=flow[T]; cap[(lst[p]&1)?lst[p]+1:lst[p]-1]+=flow[T]; p=pre[p]; } } } int main() { m=read();n=read();S=1;T=m+n+2; for(int i=1;i<=m;i++) { int ai=read(); add_e(S,i+1,0,ai); add_e(i+1,S,0,0); } for(int i=1;i<=n;i++) { int bi=read(); add_e(i+m+1,T,0,bi); add_e(T,i+m+1,0,0); } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { int cij=read(); add_e(i+1,j+m+1,cij,inf); add_e(j+m+1,i+1,-cij,0); } } MinCostMaxFlow(1); printf("%d\n",ans); for(int i=2;i<=tot;i+=2){cap[i-1]+=cap[i];cap[i]=0;} ans=0; MinCostMaxFlow(-1); printf("%d\n",ans); return 0; }
- 1
信息
- ID
- 2969
- 时间
- 1000ms
- 内存
- 250MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者