[图论] NKOJ 1952 运输问题
2017-07-09 16:05
169 查看
P1952【线性规划与网络流24题 17】运输问题
时间限制 : 10000 MS 空间限制 : 65536 KB
问题描述
W公司有m个仓库和n 个零售商店。第i 个仓库有ai个单位的货物;第j个零售商店需要bj个单位的货物。
货物供需平衡,即sigma(ai)==sigma(bj)。
从第i个仓库运送每单位货物到第j个零售商店的费用为Cij。试设计一个将仓库中所有货物运送到零售商店的运输方案,
使总运输费用最少。
输入格式
第1行有2 个正整数m和n,分别表示仓库数和零售商店数。
接下来的一行中有m个正整数ai,1≤i≤m,表示第i个仓库有ai个单位的货物。
再接下来的一行中有n个正整数bj,1≤j≤n,表示第j个零售商店需要bj个单位的货物。
接下来的m行,每行有n个整数,表示从第i个仓库运送每单位货物到第j个零售商店的费用Cij。
输出格式
程序运行结束时,将计算出的最少运输费用和最多运输费用输出
样例输入
2 3
220 280
170 120 210
77 39 105
150 186 122
样例输出
48500
69140
提示
1<=n,m<=100
0<=Ai,Bi,Cij<=1000
一道裸题,最小费用最大流和最大费用最大流的结合。
题解:
时间限制 : 10000 MS 空间限制 : 65536 KB
问题描述
W公司有m个仓库和n 个零售商店。第i 个仓库有ai个单位的货物;第j个零售商店需要bj个单位的货物。
货物供需平衡,即sigma(ai)==sigma(bj)。
从第i个仓库运送每单位货物到第j个零售商店的费用为Cij。试设计一个将仓库中所有货物运送到零售商店的运输方案,
使总运输费用最少。
输入格式
第1行有2 个正整数m和n,分别表示仓库数和零售商店数。
接下来的一行中有m个正整数ai,1≤i≤m,表示第i个仓库有ai个单位的货物。
再接下来的一行中有n个正整数bj,1≤j≤n,表示第j个零售商店需要bj个单位的货物。
接下来的m行,每行有n个整数,表示从第i个仓库运送每单位货物到第j个零售商店的费用Cij。
输出格式
程序运行结束时,将计算出的最少运输费用和最多运输费用输出
样例输入
2 3
220 280
170 120 210
77 39 105
150 186 122
样例输出
48500
69140
提示
1<=n,m<=100
0<=Ai,Bi,Cij<=1000
一道裸题,最小费用最大流和最大费用最大流的结合。
题解:
#include<cstdio> #include<cstdlib> #include<queue> #include<memory.h> #define MAX 1000 #define inf 1e8 #define reset(x) memset(x,0,sizeof(x)) using namespace std; int t1[MAX],t2[MAX],b[MAX][MAX],c[MAX][MAX],w[MAX][MAX],path[MAX],max_flow,min_cost; int dis[MAX],pts; int flag[MAX]; int T,s=1; queue<int>q; void addflow() //修改路径值 { int flow,i; flow=inf;i=T; while(i!=s) { if(flow>c[path[i]][i])flow=c[path[i]][i]; i=path[i]; } max_flow+=flow; min_cost+=flow*dis[T]; i=T; while(i!=s) { c[path[i]][i]-=flow; c[i][path[i]]+=flow; i=path[i]; } } bool find_path(int s) //SPFA { int i; for(i=1;i<=T;i++){dis[i]=inf;path[i]=-1;flag[i]=false;} dis[s]=path[s]=0; flag[s]=true; q.push(s); while(q.size()) { int j=q.front(); q.pop(); flag[j]=false; for(i=1;i<=T;i++) { if((c[j][i]>0)&&(dis[i]>dis[j]+w[j][i])) { dis[i]=dis[j]+w[j][i]; path[i]=j; if(!flag[i]) { flag[i]=true; q.push(i); } } } } if(dis[T]<inf)return true; else return false; } int main() { int m,n; scanf("%d %d",&m,&n); T=pts=m+n+2; for(int i=1;i<=m;i++) { scanf("%d",&t1[i]); c[1][i+1]=t1[i]; } for(int i=1;i<=n;i++) { scanf("%d",&t2[i]); c[1+m+i][T]=t2[i]; /*代价默认为0,不需要重置*/ } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { scanf("%d",&b[i][j]); w[i+1][m+j+1]=b[i][j]; w[m+j+1][i+1]=-b[i][j]; c[i+1][1+m+j]=inf; } } while(find_path(s)==true) { addflow(); } printf("%d\n",min_cost); max_flow=0; min_cost=0; reset(dis); reset(path); reset(w); reset(c); for(int i=1;i<=m;i++) { c[1][i+1]=t1[i]; } for(int i=1;i<=n;i++) { c[1+m+i][T]=t2[i]; } for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { w[i+1][m+j+1]=-b[i][j]; w[m+j+1][i+1]=b[i][j]; c[i+1][1+m+j]=inf; } } while(find_path(s)==true) { addflow(); } printf("%d",-min_cost); return 0; }
相关文章推荐
- 微软过桥问题的图论解法
- TopCoder 算法比赛图论实战1—最小生成树问题
- 图论 BFS 血缘关系问题
- (转)过桥问题——图论解法
- HDU 2544 最短路 第一个图论问题。
- 微软过桥问题的图论解法
- POJ 1952 BUY LOW BUY LOWER 【DP】最长降序子序列及其计数问题
- 【图论】【RQNOJ】学生运输
- 骆驼运输香蕉问题解析
- 鲍尔.爱迪斯生前在图论中未完成的问题
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 过桥问题――图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 微软过桥问题的图论解法
- 物流公司运输最优路线问题
- 【最小费用最大流】运输问题
- 图论相关问题——持续更新ing