题目描述
WW 公司有 mm 个仓库和 nn 个零售商店。第 ii 个仓库有 a_iai? 个单位的货物;第 jj 个零售商店需要 b_jbj? 个单位的货物。
货物供需平衡,即\sum\limits_{i=1}^{m}a_i=\sum\limits_{j=1}^{n}b_ji=1∑m?ai?=j=1∑n?bj?。
从第 ii 个仓库运送每单位货物到第 jj 个零售商店的费用为 c_{ij}cij??? 。
试设计一个将仓库中所有货物运送到零售商店的运输方案,使总运输费用最少。
输入输出格式
输入格式:
第 11 行有 22 个正整数 mm 和 nn,分别表示仓库数和零售商店数。
接下来的一行中有 mm 个正整数 a_iai?,表示第 ii 个仓库有 a_iai?个单位的货物。
再接下来的一行中有 nn 个正整数 b_jbj?,表示第 jj 个零售商店需要 b_jbj? 个单位的货物。
接下来的 mm 行,每行有 nn 个整数,表示从第 ii 个仓库运送每单位货物到第 jj 个零售商店的费用 c_{ij}cij?。
输出格式:
两行分别输出最小运输费用和最大运输费用。
输入输出样例
输入样例
2 3 220 280 170 120 210 77 39 105 150 186 122
输出样例
48500 69140
说明
1≤n,m≤100
求最小费用直接套模板,最大费用取相反数,结果也取相反数即可
**模板来自kuangbin
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int MAXN=10000;//点的总数 5 const int MAXM=100000;//边的总数 6 struct Edge{ 7 int to,nxt,cap,flow,cost; 8 }edge[MAXM]; 9 int head[MAXN],tot; 10 int pre[MAXN],dis[MAXN]; 11 bool vis[MAXN]; 12 int N;//节点总个数,节点编号0~N-1 13 void init() 14 { 15 tot=0; 16 memset(head,-1,sizeof(head)); 17 } 18 void addedge(int u,int v,int cap,int cost) 19 { 20 edge[tot].to=v; edge[tot].cap=cap; edge[tot].cost=cost; 21 edge[tot].flow=0; edge[tot].nxt=head[u]; head[u]=tot++; 22 23 edge[tot].to=u; edge[tot].cap=0; edge[tot].cost=-cost; 24 edge[tot].flow=0; edge[tot].nxt=head[v]; head[v]=tot++; 25 } 26 bool spfa(int s,int t) 27 { 28 queue<int>q; 29 for(int i=0;i<N;i++) 30 { 31 dis[i]=inf; 32 vis[i]=false; 33 pre[i]=-1; 34 } 35 dis[s]=0; 36 vis[s]=true; 37 q.push(s); 38 while(!q.empty()) 39 { 40 int u=q.front(); q.pop(); 41 vis[u]=false; 42 for(int i=head[u];i!=-1;i=edge[i].nxt) 43 { 44 int v=edge[i].to; 45 if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost) 46 { 47 dis[v]=dis[u]+edge[i].cost; 48 pre[v]=i; 49 if(!vis[v]) 50 { 51 vis[v]=true; 52 q.push(v); 53 } 54 } 55 } 56 } 57 if(pre[t]==-1) return false; 58 else return true; 59 } 60 int MCMF(int s,int t,int &cost) 61 { 62 int flow=0; 63 cost=0; 64 while(spfa(s,t)) 65 { 66 int minn=inf; 67 for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) 68 { 69 if(minn>edge[i].cap-edge[i].flow) 70 minn=edge[i].cap-edge[i].flow; 71 } 72 for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) 73 { 74 edge[i].flow+=minn; 75 edge[i^1].flow-=minn; 76 cost+=edge[i].cost*minn; 77 } 78 flow+=minn; 79 } 80 return flow; 81 } 82 int c[200][200],a[200],b[200]; 83 int main() 84 { 85 ios::sync_with_stdio(false); 86 cin.tie(0);cout.tie(0); 87 int n,m; 88 cin>>n>>m; 89 int s=0,t=n+m+1; 90 N=t+1; 91 init(); 92 for(int i=1;i<=n;i++) 93 { 94 cin>>a[i]; 95 addedge(s,i,a[i],0); 96 } 97 for(int i=1;i<=m;i++) 98 { 99 cin>>b[i]; 100 addedge(i+n,t,b[i],0); 101 } 102 for(int i=1;i<=n;i++) 103 { 104 for(int j=1;j<=m;j++) 105 { 106 cin>>c[i][j]; 107 addedge(i,j+n,inf,c[i][j]); 108 } 109 } 110 int cost=0; 111 MCMF(s,t,cost); 112 cout<<cost<<endl; 113 init(); 114 for(int i=1;i<=n;i++) addedge(s,i,a[i],0); 115 for(int i=1;i<=m;i++) addedge(i+n,t,b[i],0); 116 for(int i=1;i<=n;i++) 117 { 118 for(int j=1;j<=m;j++) 119 { 120 addedge(i,j+n,inf,-c[i][j]); 121 } 122 } 123 cost=0; 124 MCMF(s,t,cost); 125 cout<<-cost<<endl; 126 return 0; 127 }
原文地址:https://www.cnblogs.com/scott527407973/p/9861379.html
时间: 2024-10-06 18:57:51