【网络流24题】运输问题(费用流)(网络费用流量)

【网络流24题】运输问题

题目描述 Description

W 公司有m个仓库和n 个零售商店。第i 个仓库有ai 个单位的货物;第j 个零售商店
需要bj个单位的货物。货物供需平衡,即  sum(si)=sum(bj)
。从第i 个仓库运送每单位货物到
第j 个零售商店的费用为cij 。试设计一个将仓库中所有货物运送到零售商店的运输方案,
使总运输费用最少。
编程任务:
对于给定的m 个仓库和n 个零售商店间运送货物的费用,计算最优运输方案和最差运输方案。

输入描述 Input Description

的第1行有2 个正整数m和n,分别表示仓库数和
零售商店数。接下来的一行中有m个正整数ai ,1≤i≤m,表示第i个仓库有ai 个单位的货
物。再接下来的一行中有n个正整数bj ,1≤j≤n,表示第j个零售商店需要bj 个单位的货
物。接下来的m行,每行有n个整数,表示从第i 个仓库运送每单位货物到第j个零售商店
的费用cij 。

输出描述 Output Description

将计算出的最少运输费用和最多运输费用输出

样例输入 Sample Input

2 3
220 280
170 120 210
77 39 105
150 186 122

样例输出 Sample Output

48500
69140

一道水题,网络流24题需要吐槽了,上下界的网络流没有

跑得挺快的。

很好构图,就是S向左边的点,连ai个单位,费用为0,右边向T连bi个单位,费用为0

然后左边向右边流量无限,费用c[i][j],即可,hh。

  1 #include<cstring>
  2 #include<cmath>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<cstdio>
  6 #include<queue>
  7 
  8 #define N 2007
  9 #define M 1000007
 10 #define inf 1000000007
 11 using namespace std;
 12 inline int read()
 13 {
 14     int x=0,f=1;char ch=getchar();
 15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
 16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
 17     return x*f;
 18 }
 19 
 20 int m,n,S,T;
 21 int cnt=1,head[N],next[M],rea[M],val[M],cost[M];
 22 int c[N][N],a[N],b[N];
 23 int dis[N],flag[N];
 24 struct Node
 25 {
 26     int e,fa;
 27     void init(){e=fa=-1;}
 28 }pre[N];
 29 
 30 void add(int u,int v,int fee,int pay)
 31 {
 32     next[++cnt]=head[u];
 33     head[u]=cnt;
 34     rea[cnt]=v;
 35     val[cnt]=fee;
 36     cost[cnt]=pay;
 37 }
 38 void build(int k)
 39 {
 40     memset(head,-1,sizeof(head));cnt=1;
 41     for (int i=1;i<=m;i++)
 42     {
 43         int x=a[i];
 44         add(S,i,x,0),add(i,S,0,0);
 45     }
 46     for (int i=1;i<=n;i++)
 47     {
 48         int x=b[i];
 49         add(m+i,T,x,0),add(T,m+i,0,0);
 50     }
 51     for (int i=1;i<=m;i++)
 52         for (int j=1;j<=n;j++)
 53         {
 54             int x=c[i][j];
 55             add(i,m+j,inf,x*k),add(m+j,i,0,-x*k);
 56         }
 57 }
 58 bool Spfa()
 59 {
 60     for (int i=S;i<=T;i++)
 61         dis[i]=inf,flag[i]=0,pre[i].init();
 62     queue<int>q;q.push(S);
 63     dis[S]=0,flag[S]=1;
 64     while(!q.empty())
 65     {
 66         int u=q.front();q.pop();
 67         for (int i=head[u];i!=-1;i=next[i])
 68         {
 69             int v=rea[i],fee=cost[i];
 70             if ((dis[v]>dis[u]+fee)&&val[i]>0)
 71             {
 72                 dis[v]=dis[u]+fee;
 73                 pre[v].e=i,pre[v].fa=u;
 74                 if (!flag[v])
 75                 {
 76                     flag[v]=1;
 77                     q.push(v);
 78                 }
 79             }
 80         }    
 81         flag[u]=0;
 82     }
 83     if (dis[T]==inf) return 0;
 84     else return 1;
 85 }
 86 int mfmc()
 87 {
 88     int flow=0,res=0;
 89     while(Spfa())
 90     {
 91         int x=inf;
 92         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
 93         {
 94             int e=pre[i].e;
 95             x=min(x,val[e]);
 96         }
 97         flow+=x,res+=dis[T]*x;
 98         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
 99         {
100             int e=pre[i].e;
101             val[e]-=x,val[e^1]+=x;
102         }
103     }
104     return res;
105 }
106 int main()
107 {
108     m=read(),n=read();S=0,T=n+m+1;
109     for (int i=1;i<=m;i++) a[i]=read();
110     for (int i=1;i<=n;i++) b[i]=read();
111     for (int i=1;i<=m;i++)
112         for (int j=1;j<=n;j++)
113             c[i][j]=read();
114     build(1);
115     printf("%d\n",mfmc());
116     build(-1);
117     printf("%d\n",-mfmc());
118 }

 

posted @ 2017-11-30 20:32  Kaiser-  阅读(352)  评论(0编辑  收藏  举报