洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题【最小/大费用流】题解+AC代码
题目描述
有 n 件工作要分配给 n 个人做。第 i 个人做第 j 件工作产生的效益为c ij。 试设计一个将 n 件工作分配给 n 个人做的分配方案,使产生的总效益最大。
输入格式:
文件的第 1 行有 1 个正整数 n,表示有 n 件工作要分配给 n 个人做。接下来的 n 行中,每行有 n 个整数c ij,表示第 i 个人做第 j 件工作产生的效益为c ij 。
输出格式:
两行分别输出最小总效益和最大总效益。
输入样例
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
输出样例
5
14
说明
1001≤n≤100
题目分析
首先将讲讲最小收益
超级源点向每个工人连边
容量为1,费用为0
表示限制每个工人只能有一个工作
每个工人向每个工作连边
容量为1,费用为既定收益
这样当这条边有流时
费用即为收益
每个工作向超级汇点连边
容量为1,费用为0
表示限制每个工作只能被做一次
然后跑费用流就可以了
最大收益,即最大费用流
将原图中的边的费用全部取反
然后跑费用流
最后费用取反即可
这里由于要跑两次费用流
蒟蒻的我只想到了把原来存边的数组开了二维
即E[0][]表示最小费用用的图,E[1][]表示最大费用用的图
不知道有没有更好的办法
有没有哪位daolao教教我QAQ
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int inf=2139062143;
int m,n;
int s=0,t;
struct node{int v,f,c,nxt;}E[2][1000010];
int head[2][1000010];//这里是蒟蒻开二维存图的方式
int d[2][1000010];
bool vis[1000010];
int ans,tot=1;
int read()
{
int f=1,x=0;
char ss=getchar();
while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
return f*x;
}
void add(int u,int v,int f,int c,int p)
{
E[p][++tot].nxt=head[p][u];
E[p][tot].v=v;
E[p][tot].f=f;
E[p][tot].c=c;
head[p][u]=tot;
}
bool bfs(int p)
{
memset(d,127,sizeof(d)); d[p][s]=0;
queue<int> q; q.push(s); vis[s]=true;
while(!q.empty())
{
int u=q.front();
q.pop(); vis[u]=false;
for(int i=head[p][u];i;i=E[p][i].nxt)
{
int v=E[p][i].v;
if(E[p][i].f&&d[p][v]>d[p][u]+E[p][i].c)
{
d[p][v]=d[p][u]+E[p][i].c;
if(!vis[v])
{
q.push(v);
vis[v]=true;
}
}
}
}
return d[p][t]!=inf;
}
int dfs(int u,int cap,int p)
{
if(u==t)
return cap;
int flow=cap;
vis[u]=true;
for(int i=head[p][u];i;i=E[p][i].nxt)
{
int v=E[p][i].v;
if(d[p][v]==d[p][u]+E[p][i].c&&E[p][i].f&&flow&&!vis[v])
{
int f=dfs(v,min(E[p][i].f,flow),p);
flow-=f;
E[p][i].f-=f;
E[p][i^1].f+=f;
ans+=E[p][i].c*f;
}
}
vis[u]=false;
return cap-flow;
}
int main()
{
n=read();
t=n*2+1;
for(int i=1;i<=n;i++)
{
add(s,i,1,0,0);add(i,s,0,0,0);
add(s,i,1,0,1);add(i,s,0,0,1);
//超源向工人连边
add(i+n,t,1,0,0);add(t,i+n,0,0,0);
add(i+n,t,1,0,1);add(t,i+n,0,0,1);
//工作向超汇连边
}
for(int i=1;i<=n;i++)
{
for(int j=n+1;j<=n*2;j++)
{
int c=read();
add(i,j,1,c,0);add(j,i,0,-c,0);
add(i,j,1,-c,1);add(j,i,0,c,1);
//工人向工作连边
}
}
while(bfs(0))//最小费用流
dfs(s,inf,0);
cout<<ans<<endl;
ans=0;
while(bfs(1))//最大费用流
dfs(s,inf,1);
cout<<-ans<<endl;
return 0;
}
洛谷P4014 分配问题【最小/大费用流】题解+AC代码的更多相关文章
- 洛谷 P4014 分配问题 【最小费用最大流+最大费用最大流】
其实KM更快--但是这道题不卡,所以用了简单粗暴的费用流,建图非常简单,s向所有人连流量为1费用为0的边来限制流量,所有工作向t连流量为1费用为0的边,然后对应的人和工作连(i,j,1,cij),跑一 ...
- 洛谷P4014 分配问题(费用流)
传送门 可以把原图看做一个二分图,人在左边,任务在右边,求一个带权的最大和最小完美匹配 然而我并不会二分图做法,所以只好直接用费用流套进去,求一个最小费用最大流和最大费用最大流即可 //minamot ...
- 洛谷P4014 分配问题(费用流)
题目描述 有 nn 件工作要分配给 nn 个人做.第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij .试设计一个将 nn 件工作分配给 nn 个人做的分配方案,使产生的总效益最大. ...
- 洛谷——P4014 分配问题
P4014 分配问题 题目描述 有 nn 件工作要分配给 nn 个人做.第 ii 个人做第 jj 件工作产生的效益为 c_{ij}cij .试设计一个将 nn 件工作分配给 nn 个人做的分配方案, ...
- 洛谷P2517 HAOI2010 订货 (费用流)
标准的费用流问题,关键在于巧妙地建模 一共有n个月份,源点设为0,汇点设为n+1 1.源点向所有月份连边,容量为正无穷,费用为该月进货的费用 2.每个月向下一个月连边,容量为仓库容量,费用为存货费用 ...
- 洛谷 1004 dp或最大费用流
思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...
- 洛谷P4003 无限之环(费用流)
传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...
- 洛谷P4012 深海机器人问题(费用流)
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...
- 洛谷P4014分配问题——网络流24题
题目:https://www.luogu.org/problemnew/show/P4014 最大/小费用最大流裸题. 代码如下: #include<iostream> #include& ...
随机推荐
- [SinGuLaRiTy] NOIP互测模拟赛
[SinGuLaRiTy-1045] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 源文件名 输入输出文件 时间限制 内存限制 淘气的cch ...
- visual studio 中无法删除项目或者文件
vs 2012添加新项目或者类库后,里边的class文件,我不想要,就把它删除.但是删除的时候,报如下图的错误,我删除新建的项目或类库的时候,也报类似的错误,怎么解决? window系统是新安装的.也 ...
- pandas读取excel中指定数据的行数
shuju = pd.read_excel(filename) loandata = pd.DataFrame(shuju) ncol = (len(loandata.keys())) data = ...
- navicat的简单使用
navicat的简单使用: 连接: 输入ip地址,端口,用户名,密码 新建数据库: 数据库名,字符编码一定要选择utf-8 新建表: 字段,约束条件 双击表名,自己打开表,点击空列,添加数据,ctl+ ...
- java 基本数据类型与变量类型
Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. byte,short,char,int,long,float,double Java语言支持的变 ...
- 【转】ArcGIS中File Geodatabase与Personal Geodatabase的区别
原文地址:ArcGIS中File Geodatabase与Personal Geodatabase的区别作者:最爱忆宝贝 一.平台支援: 1.Personal Geodatabase:仅可在Windo ...
- 【转】GPS基线解算模式
GPS基线向量是利用2台或2台以上GPS接 收机所采集的同步观测数据形成的差分观测值,通过参数估计得方法所计算出的两两接收机间的三维坐标差.与常规地面测量中所测定的基线边长不同,基线向量是 既具有长度 ...
- 面试中的TCP协议
TCP的三次握手和四次挥手 三次握手 TCP连接是通过三次握手来连接的. 第一次握手 当客户端向服务器发起连接请求时,客户端会发送同步序列标号SYN到服务器,在这里我们设SYN为x,等待服务器确认,这 ...
- [C#][Newtonsoft.Json] Newtonsoft.Json 序列化时的一些其它用法
Newtonsoft.Json 序列化时的一些其它用法 在进行序列化时我们一般会选择使用匿名类型 new { },或者添加一个新类(包含想输出的所有字段).但不可避免的会出现以下情形:如属性值隐藏(敏 ...
- js和java中使用正则表达式校验邮箱
问题:经常在项目中要校验邮箱? 邮箱格式:首位必须为字母,必须包含一个@符号,并且@之后有个名字,之后还有个.,再有一个后缀名 例如:wyp55023@163.com 一.java中代码如下: Str ...