【网络流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 个人做第j件工作产生的效益为cij

输出描述 Output Description

将计算出的最小总效益和最大总效益输出

样例输入 Sample Input

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

样例输出 Sample Output

5
14

又是一道无数据范围的题目,无语了,开了2000

这是道裸题吧,S向左边流量为1,费用为0,

左边向右边,流量为1,费用a[i][j],

右边向汇点,流量为1,费用为0。

  1 #include<cstring>
  2 #include<cmath>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<cstdio>
  6 #include<queue>
  7
  8 #define N 2007
  9 #define M 1000007
 10 #define inf 1000000007
 11 using namespace std;
 12 inline int read()
 13 {
 14     int x=0,f=1;char ch=getchar();
 15     while(ch>‘9‘||ch<‘0‘){if (ch==‘-‘) f=-1;ch=getchar();}
 16     while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
 17     return x*f;
 18 }
 19
 20 int n,S,T;
 21 int cnt=1,head[N],rea[M],val[M],cost[M],next[M];
 22 int dis[N],flag[N],a[N][N];
 23 struct Node
 24 {
 25     int e,fa;
 26     void init(){e=fa=-1;}
 27 }pre[N];
 28
 29 void add(int u,int v,int fee,int pay)
 30 {
 31     next[++cnt]=head[u];
 32     head[u]=cnt;
 33     rea[cnt]=v;
 34     val[cnt]=fee;
 35     cost[cnt]=pay;
 36 }
 37 void build(int k)
 38 {
 39     cnt=1,memset(head,-1,sizeof(head));
 40     for (int i=1;i<=n;i++)
 41         add(S,i,1,0),add(i,S,0,0);
 42     for (int i=1;i<=n;i++)
 43         add(i+n,T,1,0),add(T,i+n,0,0);
 44     for (int i=1;i<=n;i++)
 45         for (int j=1;j<=n;j++)
 46             add(i,j+n,1,a[i][j]*k),add(j+n,i,0,-a[i][j]*k);
 47 }
 48 bool Spfa()
 49 {
 50     for (int i=S;i<=T;i++)
 51         dis[i]=inf,flag[i]=0,pre[i].init();
 52     queue<int>q;q.push(S);
 53     dis[S]=0,flag[S]=1;
 54     while(!q.empty())
 55     {
 56         int u=q.front();q.pop();
 57         for (int i=head[u];i!=-1;i=next[i])
 58         {
 59             int v=rea[i],fee=cost[i];
 60             if ((dis[v]>dis[u]+fee)&&val[i]>0)
 61             {
 62                 dis[v]=dis[u]+fee;
 63                 pre[v].e=i,pre[v].fa=u;
 64                 if (!flag[v])
 65                 {
 66                     flag[v]=1;
 67                     q.push(v);
 68                 }
 69             }
 70         }
 71         flag[u]=0;
 72     }
 73     if (dis[T]==inf) return 0;
 74     else return 1;
 75 }
 76 int mfmc()
 77 {
 78     int flow=0,res=0;
 79     while(Spfa())
 80     {
 81         int x=inf;
 82         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
 83         {
 84             int e=pre[i].e;
 85             x=min(x,val[e]);
 86         }
 87         flow+=x,res+=dis[T]*x;
 88         for (int i=T;pre[i].fa!=-1;i=pre[i].fa)
 89         {
 90             int e=pre[i].e;
 91             val[e]-=x,val[e^1]+=x;
 92         }
 93     }
 94     return res;
 95 }
 96 int main()
 97 {
 98     n=read(),S=0,T=n*2+1;
 99     for (int i=1;i<=n;i++)
100         for (int j=1;j<=n;j++)
101             a[i][j]=read();
102     build(1);printf("%d\n",mfmc());
103     build(-1);printf("%d\n",-mfmc());
104 }
时间: 2024-10-10 22:11:20

【网络流24题】分配问题(二分图最佳匹配)(费用流)的相关文章

【Codevs1237&amp;网络流24题餐巾计划】(费用流)

题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同. 假设第 i 天需要 ri块餐巾(i=1,2,-,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分: 或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分: 或者送到慢洗部,洗一块需 n 天(n>m),其费用为 s<f 分.每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗. 但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量.试设计一个算法为餐厅合理地安排好 N 天

【网络流24题】No.18 分配问题 (二分图最佳匹配 费用流|KM)

[题意] 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为 cij . 试设计一个将n 件工作分配给 n 个人做的分配方案, 使产生的总效益最大. 输入文件示例input.txt52 2 2 1 22 3 1 2 42 0 1 1 12 3 4 3 33 2 1 2 1 输出文件示例output.txt514 [分析] 很裸的..二分图最大权匹配. 等一下可以打一下KM... 1 #include<cstdio> 2 #include<cstdlib>

[网络流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 个

【网络流24题】圆桌聚餐(最大流)

[网络流24题]圆桌聚餐(最大流) 题面 Cogs 题解 这道题很简单 首先每个单位的人数限制 直接从源点向单位连边,容量为人数 同样的, 每个桌子向汇点连边,容量为可以坐的人数 因为每个桌子只能够做一个该单位的人 所以,每个单位向桌子连边,容量为1 然后跑一边最大流求方案就行了 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath&

LiberOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

#6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 G 公司有 n nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n nn 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入格式 文件的第 1 11 行中有 1 11 个正整数 n nn,表示有 n nn 个仓库.第 2 22 行中有 n nn 个

BZOJ 1221 HNOI 2001 软件开发/网络流24题 餐巾计划问题 最小费用最大流

题目大意:有一个软件公司,每天需要给一些员工准备消毒毛巾,这些毛巾可以循环利用,但是需要消毒.可以将毛巾送去消毒,有两种方式,A天fA花费,B天fB花费.或者还可以直接买新毛巾,问为了满足员工的需求,至少需要花多少钱. 思路:经典的费用流问题.将每一天拆点,S向每一天<<1连边,约束每一天需要多少毛巾:每一天<<1|1向T连边,约束每一天需要的毛巾.每一天<<1向这一天清洗的毛巾能够使用的那一天<<1|1,注意A和B.毛巾可以延后使用,那么每一天<&l

P2764 [网络流24题]最小路径覆盖问题[最大流]

地址 这题有个转化,求最少的链覆盖→即求最少联通块. 设联通块个数$x$个,选的边数$y$,点数$n$个 那么有 $y=n-x$   即  $x=n-y$ 而n是不变的,目标就是在保证每个点入度.出度不大于1的前提下让选的边尽可能地多. 下面网络流建模. 利用二分图匹配建图,左右两点集都包含 n 个点,左点集代表 u 的出度,右点集代表 u 的入度.对于原图中的边 (u,v),从 左边的u点 向 右边的v点 连一条容量为 1 的 边,左点集与超级源点.右点集与超级汇点都分别连一条容量 1 的边,

【网络流24题】二分图点权最大独立集(方格取数问题)

Description 在一个有m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法. 编程任务:对于给定的方格棋盘,按照取数要求编程找出总和最大的数. Input 第1 行有2 个正整数m和n,分别表示棋盘的行数和列数.接下来的m行,每行有n个正整数,表示棋盘方格中的数. Output 程序运行结束时,将取数的最大总和输出 Sample Input 3 3 1 2 3 3 2 3 2 3 1 Sa

cogs_14_搭配飞行员_(二分图匹配+最大流,网络流24题#01)

描述 http://cojs.tk/cogs/problem/problem.php?pid=14 有一些正飞行员和副飞行员,给出每个正飞行员可以和哪些副飞行员一起飞.一架飞机上必须一正一副,求最多多少飞机可以飞. 分析 裸的二分图匹配... 请叫我水题小王子... 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=100+5,INF=0x7fffffff; 5 int n,m,cnt=1; 6 int l