看了下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. 从Python安装到语法基础,这才是初学者都能懂的爬虫教程

    Python和PyCharm的安装:学会Python和PyCharm的安装方法 变量和字符串:学会使用变量和字符串的基本用法 函数与控制语句:学会Python循环.判断语句.循环语句和函数的使用 Py ...

  2. python做中学(二)bool()函数的用法

    定义: bool() 函数用于将给定参数转换为布尔类型,如果没有参数,返回 False. bool 是 int 的子类. 语法: 以下是 bool() 方法的语法: class bool([x] 参数 ...

  3. Mysql - 存储过程 - 定时删表

    在工业监控里面, 需要对每天的数据, 进行记录, 时间长了之后, 数据库很容易撑爆. 这时候, 如果允许, 可以对之前的数据进行一次清除, 只记录几个月内的数据. delimiter $ DROP P ...

  4. sql server 列字段拼接 —— STUFF

    原始数据: sql语句 SELECT DISTINCT l.family_id, )) ,,'' ) isc_id FROM dbo.Addresses l 结果数据:

  5. GO基础之函数

    一.Go语言函数的格式 函数构成了代码执行的逻辑结构,在Go语言中,函数的基本组成为:关键字 func.函数名.参数列表.返回值.函数体和返回语句,每一个程序都包含很多的函数,函数是基本的代码块. 函 ...

  6. JavaWeb之servlet(2)

    servlet(2) ServletContext servlet的上下文 每个jvm的虚拟机中的每个web工程都只有一个ServletContext工程,即在一个web工程中,无论写了多少个Java ...

  7. 漫谈golang设计模式 工厂模式

    工厂模式 意义:创建过程交给专门的工厂子类去完成.定义一个抽象的工厂类,再定义具体的工厂类来生成子类等,它们实现在抽象按钮工厂类中定义的方法.这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引 ...

  8. 在vcs中编译及运行测试E203例子

    E203的Makefile默认是调用 iverilog编译rtl,我们可以做如下修改,使其支持vcs编译. 1. 首先修改e200_opensource/tb/tb_top.v, 增加dump波形的两 ...

  9. Dynamics CRM定制子网格添加按钮实例之一

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复221或者20160430可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...

  10. php 的定界符 <<<eof

    PHP是一个Web编程语言,在编程过程中难免会遇到用echo来输出大段的html和javascript脚本的情况,如果用传统的输出方法 ——按字符串输出的话,肯定要有大量的转义符来对字符串中的引号等特 ...