看了下SPFA题解,一个一个太麻烦了,另一个写的很不清楚,而且注释都变成了"????"不知道怎么过的,于是自己来一发SPFA算法。

Part 1.题意

M 个仓库,卖给 N 个商店,两个问,第一问求运价最小值,第二问最大值。

显然是一个最小费用最大流(MCMF)。

Part 2.思路

1.连让每个仓库连接一个超级源点 SS ,费用(dis)为0,流量为仓库的流量,表示每个仓库最多可以运出多少货物。

2.让每一个仓库连接每一家商店,边权为 cost[i][j] ,其中,i为仓库编号,j为商店编号编号,流量为 need[j] ,其实流量可以取得范围是  [need[j]...INF] ,另外如果出现 need[j] <这个仓库货物量的情况也可以不怕(这时候取值的下限变成 min(hw[i],need[j]) ) hw指的是这家仓库的货物,还有注意编号的范围(我默认超级源点是 00 ,仓库是 1……n ,商店是 n+1……n+m ,超级汇点是 10000)

3.让每一家商店连接超级汇点 TT

图像帮助理解: 

Part 3.代码

现在代码就好办了 注释给的很清楚

 #include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm> #define I_copy_this_answer return 0; using namespace std; int n,m,head[],size=;
int mmx=,mincost,maxwater;
int flow[];
int need[],cost[][];
int pre[],las[],dis[],vis[],hw[]; struct edge{
int next,to,dis,flow;
}e[]; void addedge(int next,int to,int dis,int flow)
{
e[++size].to=to;
e[size].dis=dis;
e[size].flow=flow;
e[size].next=head[next];
head[next]=size;
} int spfa(int s)
{
memset(flow,0x3f,sizeof(flow));
memset(dis,0x3f,sizeof(dis));
memset(vis,,sizeof(vis));
queue <int> q;
q.push(s);
dis[s]=;
vis[s]=;
pre[mmx]=-; //(其实只要不是与p直接连的点(n+1......n+m)就可以了
while(!q.empty())
{
int t=q.front();
q.pop();
vis[t]=;
int i,j,k,l;
for(i=head[t];i;i=e[i].next)
{
j=e[i].to;
k=e[i].dis;
l=e[i].flow;
if(dis[t]+k<dis[j]&&l>) //没有流量的话这条路就增广不了,最短距离是建立在增广路存在的基础上的
{
dis[j]=dis[t]+k;
las[j]=i; //las指的是这个点(j)与上个点(t)相连的边的编号
pre[j]=t; //pre指的是这条路径上这个点(j)的上一个点
flow[j]=min(flow[t],l); //把当前边流量与上个点的流量对比,解决出现仓库货物比需要的少的情况
if(!vis[j])
{
q.push(j);
vis[j]=;
}
}
}
}
return pre[mmx]!=-; //如果不是这个值就说明这个点被刷新,增广成功
} void mcmf()
{
while(spfa())
{
mincost+=dis[mmx]*flow[mmx]; //从源点出发到汇点的单位费用再乘以单位,由于每次只增广一条路,而且仓库和商店是直接连接的,可以这样写
int t=mmx;
while(t!=)
{
e[las[t]].flow-=flow[mmx]; //回溯,修改每条边的流量,因为该算法中途找到的增广路不是最后的增广路,所以这个要等到最后来改变
e[las[t]^].flow+=flow[mmx];
t=pre[t];
}
}
} void build_edge(int t)
{
int i,j;
for(i=;i<=m;i++)
{
addedge(,i,,hw[i]);
addedge(i,,,);
}
for(i=;i<=m;i++)
for(j=;j<=n;j++)
{
addedge(i,j+m,cost[i][j]*t,need[j]);
addedge(j+m,i,-cost[i][j]*t,);
}
for(i=;i<=n;i++)
{
addedge(i+m,mmx,,need[i]);
addedge(mmx,i+m,,);
}
} int main()
{
int i,j;
scanf("%d %d",&m,&n);
for(i=;i<=m;i++)
{
int t1;
scanf("%d",&hw[i]);
}
for(i=;i<=n;i++)
scanf("%d",&need[i]);
for(i=;i<=m;i++)
for(j=;j<=n;j++)
scanf("%d",&cost[i][j]); //读入,与上面的cost,need,hw如果不明白可以对照输入格式看代表什么意思
build_edge(); //建立边权为正的边,跑最小费用最大流
mcmf();//最小费用最大流(Min Cost Max Flow )的缩写
printf("%d",mincost);
maxwater=;
mincost=;
size=;
memset(head,,sizeof(head));
build_edge(-);
mcmf();
printf("\n%d",-mincost);
I_copy_this_answer
}

洛谷P4015 运输问题 网络流24题的更多相关文章

  1. 洛谷P4011 【网络流24题】 孤岛营救问题 (BFS+状压)

    一道妙题啊......(不知道为什么这道题的标签是网络流,不需要用网络流啊) 如果没有门和钥匙,连边(边权为1)求最短路就行了. 但是有这两个因素的限制,我们采用分层建图的思想,一共2p层,每层对应持 ...

  2. 洛谷P4014分配问题——网络流24题

    题目:https://www.luogu.org/problemnew/show/P4014 最大/小费用最大流裸题. 代码如下: #include<iostream> #include& ...

  3. 洛谷P4015 运输问题(费用流)

    传送门 源点向仓库连费用$0$,流量为储量的边,商店向汇点连费用$0$,流量为需求的边,然后仓库向商店连流量$inf$,费用对应的边,跑个费用流即可 //minamoto #include<io ...

  4. [洛谷P4015]运输问题

    题目大意:有m个仓库和n个商店.第i个仓库有 $a_{i}$ 货物,第j个商店需要$b_{j}$个货物.从第i个仓库运送每单位货物到第j个商店的费用为$c_{i,j}$​​.求出最小费用和最大费用 题 ...

  5. 洛谷 P4015 运输问题 【最小费用最大流+最大费用最大流】

    s向仓库i连ins(s,i,a[i],0),商店向t连ins(i+m,t,b[i],0),商店和仓库之间连ins(i,j+m,inf,c[i][j]).建两次图分别跑最小费用最大流和最大费用最大流即可 ...

  6. 洛谷P4015 运输问题(费用流)

    题目描述 WW 公司有 mm 个仓库和 nn 个零售商店.第 ii 个仓库有 a_iai​ 个单位的货物:第 jj 个零售商店需要 b_jbj​ 个单位的货物. 货物供需平衡,即\sum\limits ...

  7. 洛谷P4009汽车加油行驶问题——网络流24题(最短路)

    题目:https://www.luogu.org/problemnew/show/P4009 网络流24题中不是网络流的最短路题: 把每个点拆成各个油量上的点,根据要求连边即可: 注意:点数最大为10 ...

  8. [网络流24题] 洛谷P2761 软件补丁问题

    题意:某公司发现其研制的一个软件中有 n个错误,随即为该软件发放了一批共 m 个补丁程序.对于每一个补丁 i ,都有 2 个与之相应的错误集合 B1(i)和 B2(i),使得仅当软件包含 B1(i)中 ...

  9. [洛谷P3254] [网络流24题] 圆桌游戏

    Description 假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri (i =1,2,--,m). 会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,--,n) ...

随机推荐

  1. vscode源码分析【七】主进程启动消息通信服务

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  2. 一文学会 TypeScript 的 82% 常用知识点(上)

    前端专栏 2019-11-22 19:17:55 对于前端从业者来说,TypeScript(以下简称 TS)已经不算是新技术. Vue3 的源码基于 TS 编写, Angular 项目默认支持 TS ...

  3. css兄弟选择器,+ ~选择器的区别

     壹 ❀ 引 实习生在写搜索框下拉提示时,遇到了不知道怎么解决的问题,所以来问我.效果不难,鼠标选中输入框(focus)时,展示搜索关键字相关提示,看了眼dom结构是这样的: 在她的理解里面,选中父元 ...

  4. 细数使用View UI(iView)开发中遇到的坑

    一.前言 View UI,即原先的 iView,是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品. 官网地址:https://www.iviewui.com/docs ...

  5. 基于 HTML5 WebGL 的 3D 科幻风机

    前言 许多世纪以来,风力机同水力机械一样,作为动力源替代人力.畜力,对生产力的发展发挥过重要作用.近代机电动力的广泛应用以及二十世纪50年代中东油田的发现,使风机发电机的发展缓慢下来. 70年代初期, ...

  6. idea创建maven的web项目

    前言 今天搭xfire的时候,我想对xfire进行一下测试,就想弄个web工程试试,发现网上写的很多没有用的,就自己写了一下.十分精简.也介绍了如何解决maven骨架建立项目非常慢的问题. 介绍 1. ...

  7. Java开发桌面程序学习(八)——启动浏览器或者打开资源管理器操作与hyperlink超链接的使用

    启动浏览器或者打开资源管理器 启动浏览器 java1.6版本以上,Desktop Desktop.getDesktop().browse(new URI("www.cnblogs.com/k ...

  8. ASP.NET MVC AJAX 请求中加入 antiforgerytoken 解决“所需的防伪表单字段“__RequestVerificationToken”不存在”问题

    在ASP.NET mvc中如果在表中使用了@Html.AntiForgeryToken(),ajax post不会请求成功 解决方法是在ajax中加入__RequestVerificationToke ...

  9. 只想听歌曲的高潮部分?让我用python来教你做个音乐高潮提取器!

    有些时候,我们为了设定手机铃声或者发抖音视频时,会耗费大量时间在音乐剪辑上.尤其是想发布大量抖音视频的时候,我们得收集大量的短音乐,这是一个相当耗费时间的工作.那么,这个音乐高潮的提取能不能自动化呢? ...

  10. Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的特点

    1.不变性 新的日期/时间API中,所有的类都是不可变的,这对多线程环境有好处. 比如:LocalDateTime 2.关注点分离 新的API将人可读的日期时间和机器时间(unix timestamp ...