【网络流24题】运输问题
2014年3月7日1,6360
题目描述 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 }
时间: 2024-10-06 18:57:46