1. 程式人生 > >【網絡流24題】運輸問題(費用流)(網絡費用流量)

【網絡流24題】運輸問題(費用流)(網絡費用流量)

size tle 輸出 main pre algorithm 流量 out text

【網絡流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 }

【網絡流24題】運輸問題(費用流)(網絡費用流量)