题目链接:https://cn.vjudge.net/contest/68128#problem/E

具体思路:图的建立方式, 超级源点 - >  供应商 - > 顾客 - > 超级汇点。

因为有多种商品,所以可以简化构图过程,每一次求一种商品的最小费用最大流,然后最终将所有商品的最小费用最大流的总和加起来就可以了,注意条件在代码中解释。

注意: 对于源点到供应商这一段不能设置成inf,具体例子如下所示。

s -  >s1,同时s1 - >s2,s1 - > s3。这样的话,就相当于有两条路从s出发,本来s到s1的流量总和为5,但是如果把流量设置成inf,

那么如果本来s1 - >s2,s1 - > s3这两条路的和是超过5的,也就是说按照原来的建图方式,初始从s-> s1 的流量是不够用的,如果改成inf的话,流量就够用,那么就改变题意了。

AC代码:

#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<stdio.h>
using namespace std;
# define inf 0x3f3f3f3f
# define maxn 150+100
# define ll long long
int need[maxn][maxn];
int store[maxn][maxn];
int Map[maxn][maxn][maxn];// i - > numofstore ,j- > huowu ,k - > keeper
int sum1[maxn],sum2[maxn];
int head[maxn];
int dis[maxn],prev[maxn],pree[maxn];
int vis[maxn];
int num;
struct Edge
{int to;int cost;int w;int nex;
} edge[maxn];
void addage(int fr,int to,int w,int cost)
{edge[num].to=to;edge[num].w=w;edge[num].cost=cost;edge[num].nex=head[fr];head[fr]=num++;edge[num].to=fr;edge[num].w=0;edge[num].cost=-cost;edge[num].nex=head[to];head[to]=num++;
}
bool spfa(int st,int ed)
{memset(vis,0,sizeof(vis));memset(pree,-1,sizeof(pree));memset(dis,inf,sizeof(dis));dis[st]=0;vis[st]=1;queue<int>q;q.push(st);while(!q.empty()){int top=q.front();q.pop();vis[top]=0;for(int i=head[top]; i!=-1; i=edge[i].nex){int temp=edge[i].to;if(edge[i].w>0&&dis[temp]>dis[top]+edge[i].cost){dis[temp]=dis[top]+edge[i].cost;pree[temp]=top;prev[temp]=i;if(vis[temp]==0){vis[temp]=1;q.push(temp);}}}}return pree[ed]!=-1;
}
int mincostflow(int st,int ed)
{int ans=0;while(spfa(st,ed)){int minn=inf;for(int i=ed; i!=st; i=pree[i]){minn=min(minn,edge[prev[i]].w);}ans+=minn*dis[ed];//dis代表一个单位的花费,minn代表流量。for(int i=ed; i!=st; i=pree[i]){edge[prev[i]].w-=minn;edge[prev[i]^1].w+=minn;}}return ans;
}
int main()
{int n,m,k;while(~scanf("%d%d%d",&n,&m,&k)&&(n+m+k)){int flag=0;memset(need,0,sizeof(need));memset(sum1,0,sizeof(sum1));memset(sum2,0,sizeof(sum2));memset(Map,0,sizeof(Map));for(int i=1; i<=n; i++){for(int j=1; j<=k; j++){scanf("%d",&need[i][j]);sum1[j]+=need[i][j];}}// xu qiu liangfor(int i=1; i<=m; i++){for(int j=1; j<=k; j++){scanf("%d",&store[i][j]);sum2[j]+=store[i][j];}}for(int i=1; i<=k; i++){if(sum1[i]>sum2[i])//判断能否满足构图的条件{flag=1;}}for(int h=1; h<=k; h++){for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){scanf("%d",&Map[h][j][i]);// 第j种货物从j仓库到达第i个买家的花费}}}if(flag==1)printf("-1\n");else{int ans=0;for(int h=1; h<=k; h++){memset(head,-1,sizeof(head));num=0;for(int i=1; i<=m; i++){addage(0,i,store[i][h],0);//注意这里的流量设置,不能设置成inf。}for(int i=1; i<=m; i++){for(int j=1; j<=n; j++){addage(i,j+m,inf,Map[h][i][j]);//这里的流量即可以设置成inf,也可以设置成存货。}}for(int i=1; i<=n; i++){addage(m+i,n+m+1,need[i][h],0);//这里设置成需求量。}ans+=mincostflow(0,n+m+1);}printf("%d\n",ans);}}return 0;
}

最小费用最大流+(对最小费用最大流的理解)相关推荐

  1. 费用流:最大费用最大流和最小费用最大流(模板)

    主要是思维建边,建有向边,然后跑模板就行了 可以解决KM算法所能解决的问题(完全取代) 可以解决非完备匹配问题中的最大权匹配和最小权匹配,分别对应着最大费用最大流和最小费用最大流 模板: 最大费用最大 ...

  2. 最小生成树、最大流、最小费用最大流问题精简

    最小生成树.最大流.最小费用最大流问题精简 最小生成树:   简单来说即图中一个使各点连通的N-1个边的子图,当边权和最小时为最小生成树. 经典Prim,Kruskal算法: (1)Prim:(从点出 ...

  3. 网络流中最大流和最小割算法

    学习顺序按照下图的改进历程 问题转化:寻找初始解,提升,达到条件停止 求解优化,加回溯边,画残差图,在残差图中寻找一条s可到t的路径 看最大流最小割问题,证明 除 ST外每个点的出度和入度相等,S和T ...

  4. 一种更高效的费用流算法——zkw费用流

    orz原创者zkw%%% 送上zkw神犇的blog原址:传送门 费用流建立在网络最大流的基础上,一张图中最大流有且仅有一个,但是最大流条数往往不止一条,这时候对于我们来说,可能要找出这些最大流中最小( ...

  5. 一篇网络流 基本模型超全总结(最大流 费用流 多源汇最大流 上下界可行流) 思路+代码模板

    文章目录 一.网络流与最大流 二.网络流三个基本性质 三.重要定义定理 四.最大流算法 <Ⅰ> Edmonds-Karp算法(EK算法) 1.EK算法 2.算法思想: 3.代码模板 4.模 ...

  6. [原]最大流, 最小分割分析

    1如果图G存在s-t流f,并且在剩余图Gf中没有s-t的路径, 存在一个s-t的分割cut(A, B), 且v(f) = cut(A, B),  并且f拥有最大的流值, 分割cut(A, B)拥有最小 ...

  7. 网络流——最大流和最小割

    最小割问题 ststst割:将节点划分为A,BA,BA,B两个集合,其中源节点s∈As\in As∈A且宿节点t∈Bt\in Bt∈B ststst割的容量:由集合AAA到集合BBB所有出边容量之和. ...

  8. 网络流:最大流,最小割 基本概念及算法

    原文:http://www.cnblogs.com/Booble/archive/2011/03/04/1970453.html 参考:http://community.topcoder.com/tc ...

  9. 如何快速理解最大流和最小割

    摘要: 割从哪来-------->最大流和最小割之间的等价关系的阐述. 1.问题引入 1.1思考这样一个问题:在给定的图中,如何判断一个源点s到终点t是否有路径存在呢? 我们首先想到的是用BFS ...

  10. 最大流与最小割(Maxflow与Mincut)

    传统图像主要分割算法: 基于阈值的分割 (1)固定阈值分割 (2)直方图双峰法 (3)迭代阈值图像分割 (4)自适应阈值图像分割 (5)最佳阈值法 2.基于边缘的分割 (1)Canny边缘检测器 (2 ...

最新文章

  1. python中的绘图模块turtle的使用
  2. DevIL真是好用得想哭
  3. vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
  4. 实现div在固定区域跟随鼠标移动点击拖动而产生的变化
  5. java dataset类的方法,C#中DataSet转化为实体集合类的方法
  6. 6.Springcloud的Ribbon的负载均衡算法解析及配置方式
  7. 计算机出现全部英文如何解决,电脑打开后出现很多英文怎么处理
  8. 推免生是否抢了考研生的“奶酪”
  9. Threshold函数详解
  10. 数据分析师面试题目_数据分析师面试题目
  11. 计算机系统无法启动 错误恢复怎么办,windows7恢复错误,无法进入系统最佳解决方法...
  12. asp.net打印错误日志
  13. PHP中的定界符 echo
  14. Android 11.0 充电指示灯红绿显示简单客制化
  15. php qq授权_PHP模拟QQ网页版授权登录的案例
  16. 视频导入pr一卡一卡的(解决)
  17. 振芯科技GM8285C:功能TTL转LVDS芯片简介
  18. 中央企业数字化转型的作用及意义
  19. 《那些年啊,那些事——一个程序员的奋斗史》——20
  20. vue2中的“$(this)” === JQ中$(this)--飞机票项目

热门文章

  1. [WPS]一次性解决论文插图的题注与章节号对不上问题
  2. 在php中调用java的方法
  3. 刷了OpenWrt Attitude Adjustment 12.09,很满意
  4. Apache Kafka是数据库吗?
  5. 有源雷达与无源雷达、主动雷达与被动雷达
  6. C语言中的空指针、空指针常量、NULL 0
  7. 阿里云ECS云服务器镜像的基本概念以及使用(七)
  8. GDPR: Impact to Your Data Management Landscape: Part 2
  9. Cadence 计算器使用——settling time
  10. Android RenRen SDK 接入教程