网络流24题-18
来源:互联网 发布:笑郭网络验证4.6 编辑:程序博客网 时间:2024/06/13 21:40
分配问题
«问题描述:
有 n 件工作要分配给 n 个人做。第 i 个人做第 j 件工作产生的效益为 c ij 。试设计一个将
n 件工作分配给 n 个人做的分配方案,使产生的总效益最大。
«编程任务:
对于给定的 n 件工作和 n 个人,计算最优分配方案和最差分配方案。
«数据输入:
由文件 input.txt 提供输入数据。文件的第 1 行有 1 个正整数 n,表示有 n 件工作要分配
给 n 个人做。接下来的 n 行中,每行有 n 个整数 c ij ,1≤i≤n,1≤j≤n,表示第 i 个人做
第 j 件工作产生的效益为 c ij 。
«结果输出:
程序运行结束时,将计算出的最小总效益和最大总效益输出到文件 output.txt 中。
输入文件示例
input.txt
5
2 2 2 1 2
2 3 1 2 4
2 0 1 1 1
2 3 4 3 3
3 2 1 2 1
输出文件示例
output.txt
5
14
【问题分析】
费用流问题。
【建模方法】
把所有仓库看做二分图中顶点Xi,所有零售商店看做二分图中顶点Yi,建立附加源S汇T。
1、从S向每个Xi连一条容量为仓库中货物数量ai,费用为0的有向边。
2、从每个Yi向T连一条容量为商店所需货物数量bi,费用为0的有向边。
3、从每个Xi向每个Yj连接一条容量为无穷大,费用为cij的有向边。
求最小费用最大流,最小费用流值就是最少运费,求最大费用最大流,最大费用流值就是最多运费。
【建模分析】
把每个仓库想象成一个中转站,由源点运来ai单位货物,运费为0,每个商店也为一个中转站,运向目标汇点bi单位货物。每个仓库和零售商店之间有一条道路,容量为无穷大,费用为单位运费cij。求从源点到汇点的费用流,就是运费。
#include<iostream>#include<math.h>#include<cstring>#include<algorithm>#include<set>#include<map>#include<queue>#include<cstdio>#include<vector>const int INF=0x7fffffff;const int maxn=1000;int Map[maxn+1][maxn+1];using namespace std;struct edge{ int to,cap,cost,rev;};vector<edge> G[maxn];int dist[maxn],prevv[maxn],preve[maxn];int V,S,T,N;void add_edge(int from,int to,int cap,int cost){ G[from].push_back((edge){to,cap,cost,G[to].size()}); G[to].push_back((edge){from,0,-cost,G[from].size()-1}); //cout<<from<<"to:"<<to<<" "<<cap<<" "<<cost<<endl;}int min_cost_flow(int s,int t,int f){ int res=0; while(f>0) { fill(dist,dist+V+1,INF); bool update=true; dist[s]=0; while(update) { update=false; for(int v=0;v<=V;v++) { if(dist[v]==INF) continue; for(int i=0;i<G[v].size();i++) { edge &e=G[v][i]; if(e.cap&&dist[e.to]>dist[v]+e.cost) { dist[e.to]=dist[v]+e.cost; prevv[e.to]=v; preve[e.to]=i; update=true; } } } } if(dist[t]==INF) return -1; int d=f; for(int v=t;v!=s;v=prevv[v]) d=min(G[prevv[v]][preve[v]].cap,d); f-=d; res+=d*dist[t]; for(int v=t;v!=s;v=prevv[v]) { edge &e=G[prevv[v]][preve[v]]; e.cap-=d; G[e.to][e.rev].cap+=d; } } return res;}void init(){ cin>>N; S=0; T=2*N+1; V=T; for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) cin>>Map[i][j];}void solve1(){ for(int i=1;i<=N;i++) add_edge(S,i,1,0); for(int i=1;i<=N;i++) add_edge(i+N,T,1,0); for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) add_edge(i,j+N,1,Map[i][j]); int ans=min_cost_flow(S,T,N); cout<<ans<<endl;}void solve2(){ for(int i=1;i<=N;i++) add_edge(S,i,1,0); for(int i=1;i<=N;i++) add_edge(i+N,T,1,0); for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) add_edge(i,j+N,1,-Map[i][j]); int ans=min_cost_flow(S,T,N); cout<<-ans<<endl;}int main(){ init(); solve1(); for(int i=0;i<=V;i++) G[i].clear(); solve2(); return 0;}
- 网络流24题-18
- 【网络流】网络流24题
- [网络流]: 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- [网络流24题 #18]分配问题
- 【网络流24题-18】分配问题 网络流 费用流
- 网络流24题---餐巾纸
- [网络流24题] 餐巾
- 网络流24题-2
- 网络流24题-3
- 网络流24题-4
- 网络流24题-5
- 网络流24题-6
- 网络流24题-7
- 网络流24题-8
- poj1182 食物链 (带权并查集)
- 算法 第四版 1.3.39 环形缓冲区
- 电气设备安装技术交底
- 选择排序
- 338. Counting Bits(动态规划)
- 网络流24题-18
- 909422229_三种常用定时器之Spring中Task定时器
- jmeter报错 :non http response code: org.apache.http.connectionclosedexception解决办法
- 链表 C++ 简单练习
- gdb
- 中国大学MOOC·Python网络爬虫与信息提取(二)——五个实例分析
- 深度学习系列教程
- 机票去程返程的切换效果
- 欢迎使用CSDN-markdown编辑器