亲爱的,一个货物加害者,现在遇到了一个大问题,他需要你的帮助。在他的销售区域有 N 个店主(从 1 到 N)向他储存货物,Dearboy 有M 个供应点(从 1 到 M),每个供应点提供 K 种不同的货物(从 1 到K)。一旦店主订购货物,迪尔博伊应该安排哪个供应点向店主提供多少货物,以降低总的运输成本。众所周知,从不同的货源地向不同的店主运送不同种类的一件商品的成本可能是不同的。考虑到每个货源地存放的 K 种货物,N 个店主订购的K 种货物,以及从不同货源地向不同店主运送不同种类货物的成本,您应该说明如何安排货物的供应,以使运输总成本最小化。
最小费用最大流模板~
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int maxn=1014; const int inf=1e9; int cap[maxn][maxn]; int flow[maxn][maxn]; int cost[maxn][maxn]; int n; int f;//最大流 int c;//最小费用 int st,ed; bool visit[maxn]; int pre[maxn],dist[maxn]; bool spfa () { queue<int> q; for (int u=0;u<=n;u++) { if (u==st) { q.push(u); dist[u]=0; visit[u]=true; } else { dist[u]=inf; visit[u]=false; } } while (!q.empty()) { int u=q.front(); visit[u]=false; q.pop(); for (int v=0;v<=n;v++) { if (cap[u][v]>flow[u][v]&&dist[v]>dist[u]+cost[u][v]) { dist[v]=dist[u]+cost[u][v]; pre[v]=u; if (!visit[v]) { visit[v]=true; q.push(v); } } } } if (dist[ed]>=inf) return false; return true; } void minCostMaxflow () { memset (flow,0,sizeof(flow)); c=f=0; while (spfa()) { int Min=inf; for (int u=ed;u!=st;u=pre[u]) Min=min(Min,cap[pre[u]][u]-flow[pre[u]][u]); for (int u=ed;u!=st;u=pre[u]) { flow[pre[u]][u]+=Min; flow[u][pre[u]]-=Min; } c+=dist[ed]*Min; f+=Min; } } int order[maxn][maxn]; int supply[maxn][maxn]; int tolorder[maxn]; int main() { int N,M; int K; while(scanf("%d%d%d",&N,&M,&K)!=EOF) { if(N==0&&M==0&&K==0)break; st=0; n=N+M+1; ed=n; memset(cap,0,sizeof(cap)); memset(cost,0,sizeof(cost)); for(int i=0;i<N;i++) for(int j=0;j<K;j++) scanf("%d",&order[i][j]); for(int i=0;i<M;i++) for(int j=0;j<K;j++) scanf("%d",&supply[i][j]); for(int i=0;i<K;i++) { tolorder[i]=0; for(int j=0;j<N;j++) tolorder[i]+=order[j][i]; } for(int i=1;i<=M;i++) for(int j=M+1;j<=N+M;j++) cap[i][j]=inf; bool flag=true; int ans=0; for(int i=0;i<K;i++) { for(int j=M+1;j<=M+N;j++) for(int k=1;k<=M;k++) { scanf("%d",&cost[k][j]); cost[j][k]=-cost[k][j]; } if(!flag)continue; for(int j=1;j<=M;j++) cap[st][j]=supply[j-1][i]; for(int j=1;j<=N;j++) cap[j+M][ed]=order[j-1][i]; minCostMaxflow(); if(f<tolorder[i])flag=false; else ans+=c; } if(!flag)printf("-1\n"); else printf("%d\n",ans); } return 0; }