[网络流24题] 分配问题

740. [网络流24题] 分配问题

★★   输入文件:job.in   输出文件:job.out   简单对比
时间限制:1 s   内存限制:128 MB

«问题描述:

有n件工作要分配给n个人做。第i 个人做第j 件工作产生的效益为ij c 。试设计一个将
n件工作分配给n个人做的分配方案,使产生的总效益最大。

«编程任务:

对于给定的n件工作和n个人,计算最优分配方案和最差分配方案。

«数据输入:

由文件job.in提供输入数据。文件的第1 行有1 个正整数n,表示有n件工作要分配
给n 个人做。接下来的n 行中,每行有n 个整数ij c ,1≤i≤n,1≤j≤n,表示第i 个人做
第j件工作产生的效益为ij c 。

«结果输出:

程序运行结束时,将计算出的最小总效益和最大总效益输出到文件job.out中。
输入文件示例 输出文件示例
job.in

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

job.out

5

14

数据范围

N<=100

分析: 

最小费用最大流和最大费油最大流 的裸题

实现 EK(貌似zkw更优)

显示代码纯文本

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. using namespace std;
  5. const int N=210;
  6. const int inf=2e9;
  7. struct edge{int v,cap,cost,next;}e[N*N*2];int tot=1,head[N];
  8. int n,m,S,T,ans,a[N][N],dis[N],pre[N],q[N*N*2];bool vis[N];
  9. inline int read(){
  10. int x=0,f=1;char ch=getchar();
  11. // while(ch<‘0‘||ch>‘9‘){if(ch=‘-‘)f=-1;ch=getchar();}读入优化写错了,本地没检测出来。。。
  12. while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
  13. while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
  14. return x*f;
  15. }
  16. inline void add(int x,int y,int z,int cost){
  17. e[++tot].v=y;e[tot].cap=z;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot;
  18. e[++tot].v=x;e[tot].cap=0;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot;
  19. }
  20. inline bool spfa(int f){
  21. if(f)for(int i=S;i<=T;i++) dis[i]=inf,vis[i]=0;//min cost
  22. else for(int i=S;i<=T;i++) dis[i]=-inf,vis[i]=0;//max cost
  23. unsigned short h=0,t=1;q[t]=S;dis[S]=0;
  24. while(h!=t){
  25. int x=q[++h];vis[x]=0;
  26. for(int i=head[x];i;i=e[i].next){
  27. if(e[i].cap&&( (f&&dis[e[i].v]>dis[x]+e[i].cost)
  28. ||(!f&&dis[e[i].v]<dis[x]+e[i].cost) )){
  29. dis[e[i].v]=dis[x]+e[i].cost;
  30. pre[e[i].v]=i;
  31. if(!vis[e[i].v]){
  32. vis[e[i].v]=1;
  33. q[++t]=e[i].v;
  34. }
  35. }
  36. }
  37. }
  38. if(f) return dis[T]!=inf;
  39. else return dis[T]!=-inf;
  40. }
  41. inline int augment(){
  42. int flow=inf;
  43. for(int i=T;i!=S;i=e[pre[i]^1].v) flow=min(flow,e[pre[i]].cap);
  44. for(int i=T;i!=S;i=e[pre[i]^1].v){
  45. e[pre[i]].cap-=flow;
  46. e[pre[i]^1].cap+=flow;
  47. }
  48. return dis[T]*flow;
  49. }
  50. inline void init(){
  51. n=read();
  52. for(int i=1;i<=n;i++){
  53. for(int j=1;j<=n;j++){
  54. a[i][j]=read();
  55. }
  56. }
  57. }
  58. inline void mapping(){
  59. S=0,T=n<<1|1;
  60. tot=1;memset(head,0,sizeof head);
  61. for(int i=1;i<=n;i++) add(S,i,1,0);
  62. for(int i=1;i<=n;i++) add(i+n,T,1,0);
  63. for(int i=1;i<=n;i++){
  64. for(int j=1;j<=n;j++){
  65. add(i,j+n,1,a[i][j]);
  66. }
  67. }
  68. }
  69. inline void work(){
  70. mapping();
  71. while(spfa(1)) ans+=augment();
  72. printf("%d\n",ans);
  73. mapping();ans=0;
  74. while(spfa(0)) ans+=augment();
  75. printf("%d\n",ans);
  76. }
  77. int main(){
  78. freopen("job.in","r",stdin);
  79. freopen("job.out","w",stdout);
  80. init();
  81. work();
  82. return 0;
  83. }
时间: 2024-11-05 14:55:37

[网络流24题] 分配问题的相关文章

【网络流24题】分配问题(二分图最佳匹配)(费用流)

[网络流24题]分配问题 2014年3月11日1,8720 题目描述 Description 有n件工作要分配给n个人做.第i 个人做第j 件工作产生的效益为ij c .试设计一个将n件工作分配给n个人做的分配方案,使产生的总效益最大.«编程任务:对于给定的n件工作和n个人,计算最优分配方案和最差分配方案. 输入描述 Input Description 第1 行有1 个正整数n,表示有n件工作要分配给n 个人做.接下来的n 行中,每行有n 个整数 cij ,1≤i≤n,1≤j≤n,表示第i 个人

「网络流24题」 18. 分配问题

「网络流24题」 18. 分配问题 <题目链接> 费用流其实是可以做这题的. 但这篇主要说一下二分图最佳完美匹配--Kuhn-Munkres(KM)算法. 工作是X部,费用是Y部,边权为工作效益. 通过X部减去/Y部增加增广路上的松弛量,修改「顶标」(又称标杆). 初始顶标:X部点:最大权出边的边权:Y部点:0. 跑出来后,所有顶标和是最大效益. 所有边取负,跑出来的和的相反数是最小效益. 具体请看此篇题解. KM写法 #include <algorithm> #include &

网络流24题之分配问题

题目链接:传送门 这道题和运输问题也是贼相似的,几乎一模一样 详细见网络流24题之分配问题 #include<bits/stdc++.h> using namespace std; typedef long long ll; int read(){ int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar(); while(c>='0'&&c<='9') x=

网络流24题 -No.18 分配问题

问题描述 有 n件工作要分配给 n个人做.第 i 个人做第 j 件工作产生的效益为c[i,j] .试设计一个将n 件工作分配给 n个人做的分配方案,使产生的总效益最大. 编程任务对于给定的 n件工作和 n 个人,计算最优分配方案和最差分配方案. 数据输入输入的第 1 行有 1 个正整数 n,表示有 n件工作要分配给 n 个人做.接下来的 n 行中,每行有 n 个整数c[i,j],1≤i≤n,1≤j≤n,表示第 i 个人做第 j 件工作产生的效益为c[i,j] . 结果输出程序运行结束时,输出最小

「网络流24题」 题目列表

「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分图最小路径覆盖 <3> 4 魔术球问题 <4> 5 圆桌问题 <5> 6 最长递增子序列问题 <6> 7 试题库问题 <7> 8 机器人路径规划问题 <8> 9 方格取数问题 二分图最大点权独立集 <9> 10 餐巾计划问题

网络流24题 部分总结

网络流24题 部分总结 慢慢写吧... 以前做过一些了: 然后发现也做了不少了,集中写一下. 警告: 题目按照随机顺序排列. 文章中只有建模的方法. 最小路径覆盖问题 http://cogs.pro:8080/cogs/problem/problem.php?pid=728 题目即题解... // It is made by XZZ #include<cstdio> #include<algorithm> #include<cstring> #define File #

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

【网络流24题----14】孤岛营救问题

孤岛营救问题 Time Limit: 1 Sec  Memory Limit: 128 MB Description 1944年,特种兵麦克接到国防部的命令.要求马上赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图.迷宫的外形是一个长方形,其南北方向被划分为 N行,东西方向被划分为 M列,于是整个迷宫被划分为 N×M个单元.每个单元的位置可用一个有序数对 (单元的行号,单元的列号)来表示.南北或东西方向相邻的 2个单元之间可能互

【网络流24题】

网络流 网络流24题 [最小路径覆盖问题] 关于输出路径,因为即使有反向弧经过左侧点也一定会改变左侧点的去向,若没连向右侧就会被更新到0,所以不用在意. mark记录有入度的右侧点,然后从没入度的右侧点开始把整条路径输出来即可. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=100000,inf=0x3f3f3f3f; int n,m,