运输问题
Description
W
公司有
第
货物供需平衡,即
∑mi=1ai=∑nj=1bj
。
从第
i
个仓库运送每单位货物到第
试设计一个将仓库中所有货物运送到零售商店的运输方案,使总运输费用最少。
编程任务:
对于给定的
m
个仓库和
Input
第
1
行有
接下来的一行中有
m
个正整数
再接下来的一行中有
n
个正整数
接下来的
m
行,每行有
Output
将计算出的最少运输费用和最多运输费用输出。
Sample Input
2 3
220 280
170 120 210
77 39 105
150 186 122
Sample Output
48500
69140
Solution
标准的最小费用流和最大费用流模板题。
感觉网络流越往后做越简单??
Code
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <queue>
- #define ss 0
- #define tt 100000
- #define INF 0x3f3f3f3f
- #define Min(x,y) ((x)<(y)?(x):(y))
- using namespace std;
- int cnt,cnt1,ans,m,n,ans0;
- int nxt[100010],head[100010],data[100010];
- int nxt1[100010],head1[100010],data1[100010];
- int flow[100010],wei[100010];
- int flow1[100010],wei1[100010];
- int dis[100010];
- int pre[100010];
- int aa[1000],bb[1000];
- queue<int>q;
- bool in_stack[100010];
- void add(int x,int y,int a,int b){
- nxt[cnt]=head[x];data[cnt]=y;wei[cnt]=-b;flow[cnt]=a;head[x]=cnt++;
- nxt[cnt]=head[y];data[cnt]=x;wei[cnt]=b;flow[cnt]=0;head[y]=cnt++;
- nxt1[cnt1]=head1[x];data1[cnt1]=y;wei1[cnt1]=b;flow1[cnt1]=a;head1[x]=cnt1++;
- nxt1[cnt1]=head1[y];data1[cnt1]=x;wei1[cnt1]=-b;flow1[cnt1]=0;head1[y]=cnt1++;
- }
- bool BFS(){
- memset(dis,0x3f,sizeof dis);dis[ss]=0;in_stack[ss]=true;q.push(ss);pre[ss]=pre[tt]=-1;
- while(!q.empty()){
- int now=q.front();
- q.pop();
- in_stack[now]=false;
- for(int i=head[now];i!=-1;i=nxt[i]){
- if(flow[i]!=0&&dis[data[i]]>dis[now]+wei[i]){
- dis[data[i]]=dis[now]+wei[i];
- pre[data[i]]=i^1;
- if(!in_stack[data[i]]){
- in_stack[data[i]]=true;
- q.push(data[i]);
- }
- }
- }
- }
- return pre[tt]!=-1;
- }
- void dfs(){
- int Low=INF;
- for(int i=pre[tt];i!=-1;i=pre[data[i]])Low=Min(Low,flow[i^1]);
- for(int i=pre[tt];i!=-1;i=pre[data[i]])flow[i^1]-=Low,flow[i]+=Low;
- ans+=Low*dis[tt];
- }
- bool BFS1(){
- memset(dis,0x3f,sizeof dis);dis[ss]=0;in_stack[ss]=true;q.push(ss);pre[ss]=pre[tt]=-1;
- while(!q.empty()){
- int now=q.front();
- q.pop();
- in_stack[now]=false;
- for(int i=head1[now];i!=-1;i=nxt1[i]){
- if(flow1[i]!=0&&dis[data1[i]]>dis[now]+wei1[i]){
- dis[data1[i]]=dis[now]+wei1[i];
- pre[data1[i]]=i^1;
- if(!in_stack[data1[i]]){
- in_stack[data1[i]]=true;
- q.push(data1[i]);
- }
- }
- }
- }
- return pre[tt]!=-1;
- }
- void dfs1(){
- int Low=INF;
- for(int i=pre[tt];i!=-1;i=pre[data1[i]])Low=Min(Low,flow1[i^1]);
- for(int i=pre[tt];i!=-1;i=pre[data1[i]])flow1[i^1]-=Low,flow1[i]+=Low;
- ans0+=Low*dis[tt];
- }
- int main(){
- freopen(”trans.in”,“r”,stdin);
- freopen(”trans.out”,“w”,stdout);
- memset(head,-1,sizeof head);
- memset(head1,-1,sizeof head1);
- scanf(”%d%d”,&m,&n);
- for(int i=1;i<=m;i++){
- int x;
- scanf(”%d”,&x);
- aa[i]=x;
- add(ss,i,x,0);
- }
- for(int i=1;i<=n;i++){
- int x;
- scanf(”%d”,&x);
- bb[i]=x;
- add(i+m,tt,x,0);
- }
- for(int i=1;i<=m;i++)
- for(int j=1;j<=n;j++){
- int x;
- scanf(”%d”,&x);
- add(i,j+m,Min(aa[i],bb[j]),x);
- }
- while(BFS1())dfs1();
- while(BFS())dfs();
- printf(”%d\n%d\n”,ans0,-ans);
- return 0;
- }