POJ 2516 Minimum Cost(最小费用流)
Description
It's known that the cost to transport one unit goods for different kinds from different supply places to different shopkeepers may be different. Given each supply places' storage of K kinds of goods, N shopkeepers' order of K kinds of goods and the cost to transport goods for different kinds from different supply places to different shopkeepers, you should tell how to arrange the goods supply to minimize the total cost of transport.
Input
Then come K integer matrices (each with the size N * M), the integer (this integer is belong to (0, 100)) at the i-th row, j-th column in the k-th matrix represents the cost to transport one unit of k-th goods from the j-th supply place to the i-th shopkeeper.
The input is terminated with three "0"s. This test case should not be processed.
Output
题目大意:N个客户M个仓库K种物品。已知每个客户需要的每种物品的数量,和每个仓库拥有的每种物品的数量,和每个仓库运送每种物品到每个顾客的花费,求满足所有顾客的最小花费。
思路:由于每个物品独立,分开每个物品建图。考虑物品x,建立附加源点S,从S到每个仓库连一条边,容量为该仓库拥有物品x的数量,费用为0;从每个客户连一条边到附加汇点T,容量为每个客户需要的物品x的数量,费用为0;从每个仓库连一条边到每个客户,容量为无穷大,费用为仓库到客户运输物品x的花费。求最小费用最大流,若都满流,K个物品相加就是答案。若有一个流不满,则输出-1(不能满足顾客需求)。
PS:记得读完数据。
PS2:再次提出稠密图应该用ZKW费用流。
PS3:ZKW费用流写挫了WA了一次,这玩意儿好难写……
代码(266MS):
#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std; const int MAXV = ;
const int MAXE = MAXV * MAXV;
const int INF = 0x7fffffff; struct ZEK_FLOW {
int head[MAXV], dis[MAXV];
int next[MAXE], to[MAXE], cap[MAXE], cost[MAXE];
int n, ecnt, st, ed; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge(int u, int v, int c, int w) {
to[ecnt] = v; cap[ecnt] = c; cost[ecnt] = w; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; cap[ecnt] = ; cost[ecnt] = -w; next[ecnt] = head[v]; head[v] = ecnt++;
} void SPFA() {
for(int i = ; i <= n; ++i) dis[i] = INF;
priority_queue<pair<int, int> > que;
dis[st] = ; que.push(make_pair(, st));
while(!que.empty()) {
int u = que.top().second, d = -que.top().first; que.pop();
if(d != dis[u]) continue;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(cap[p] && dis[v] > d + cost[p]) {
dis[v] = d + cost[p];
que.push(make_pair(-dis[v], v));
}
}
}
int t = dis[ed];
for(int i = ; i <= n; ++i) dis[i] = t - dis[i];
} int minCost, maxFlow;
bool vis[MAXV]; int add_flow(int u, int aug) {
if(u == ed) {
maxFlow += aug;
minCost += dis[st] * aug;
return aug;
}
vis[u] = true;
int now = aug;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(cap[p] && !vis[v] && dis[u] == dis[v] + cost[p]) {
int t = add_flow(v, min(now, cap[p]));
cap[p] -= t;
cap[p ^ ] += t;
now -= t;
if(!now) break;
}
}
return aug - now;
} bool modify_label() {
int d = INF;
for(int u = ; u <= n; ++u) if(vis[u]) {
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(cap[p] && !vis[v]) d = min(d, dis[v] + cost[p] - dis[u]);
}
}
if(d == INF) return false;
for(int i = ; i <= n; ++i) if(vis[i]) dis[i] += d;
return true;
} int min_cost_flow(int ss, int tt, int nn) {
st = ss, ed = tt, n = nn;
minCost = maxFlow = ;
SPFA();
while(true) {
while(true) {
for(int i = ; i <= n; ++i) vis[i] = ;
if(!add_flow(st, INF)) break;
}
if(!modify_label()) break;
}
return minCost;
}
} G; int n, m, k;
int need[MAXV][MAXV], have[MAXV][MAXV], sum[MAXV];
int mat[MAXV][MAXV]; int main() {
while(scanf("%d%d%d", &n, &m, &k) != EOF) {
if(n == && m == && k == ) break;
memset(sum, , sizeof(sum));
for(int i = ; i <= n; ++i)
for(int j = ; j <= k; ++j) scanf("%d", &need[i][j]), sum[j] += need[i][j];
for(int i = ; i <= m; ++i)
for(int j = ; j <= k; ++j) scanf("%d", &have[i][j]);
int ans = ; bool flag = true;
for(int x = ; x <= k; ++x) {
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) scanf("%d", &mat[i][j]);
if(!flag) continue;
G.init();
int ss = n + m + , tt = ss + ;
for(int i = ; i <= m; ++i) G.add_edge(ss, i, have[i][x], );
for(int i = ; i <= n; ++i) G.add_edge(i + m, tt, need[i][x], );
for(int i = ; i <= n; ++i)
for(int j = ; j <= m; ++j) G.add_edge(j, i + m, INF, mat[i][j]);
ans += G.min_cost_flow(ss, tt, tt);
flag = (G.maxFlow == sum[x]);
}
if(flag) printf("%d\n", ans);
else puts("-1");
}
}
POJ 2516 Minimum Cost(最小费用流)的更多相关文章
- POJ 2516 Minimum Cost 最小费用流 难度:1
Minimum Cost Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 13511 Accepted: 4628 Des ...
- POJ 2516 Minimum Cost 最小费用流
题目: 给出n*kk的矩阵,格子a[i][k]表示第i个客户需要第k种货物a[i][k]单位. 给出m*kk的矩阵,格子b[j][k]表示第j个供应商可以提供第k种货物b[j][k]单位. 再给出k个 ...
- POJ 2516 Minimum Cost (网络流,最小费用流)
POJ 2516 Minimum Cost (网络流,最小费用流) Description Dearboy, a goods victualer, now comes to a big problem ...
- Poj 2516 Minimum Cost (最小花费最大流)
题目链接: Poj 2516 Minimum Cost 题目描述: 有n个商店,m个仓储,每个商店和仓库都有k种货物.嘛!现在n个商店要开始向m个仓库发出订单了,订单信息为当前商店对每种货物的需求 ...
- POJ 2516 Minimum Cost (最小费用最大流)
POJ 2516 Minimum Cost 链接:http://poj.org/problem?id=2516 题意:有M个仓库.N个商人.K种物品.先输入N,M.K.然后输入N行K个数,每一行代表一 ...
- POJ 2516 Minimum Cost (费用流)
题面 Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area ...
- POJ - 2516 Minimum Cost 每次要跑K次费用流
传送门:poj.org/problem?id=2516 题意: 有m个仓库,n个买家,k个商品,每个仓库运送不同商品到不同买家的路费是不同的.问为了满足不同买家的订单的最小的花费. 思路: 设立一个源 ...
- POJ 2516 Minimum Cost(拆点+KM完备匹配)
题目链接:http://poj.org/problem?id=2516 题目大意: 第一行是N,M,K 接下来N行:第i行有K个数字表示第i个卖场对K种商品的需求情况 接下来M行:第j行有K个数字表示 ...
- POJ 2516 Minimum Cost [最小费用最大流]
题意略: 思路: 这题比较坑的地方是把每种货物单独建图分开算就ok了. #include<stdio.h> #include<queue> #define MAXN 500 # ...
随机推荐
- o'Reill的SVG精髓(第二版)学习笔记——第一章
1.1图形系统 计算机中描述图形信息的两大系统是栅格系统(raster graphics)和矢量图形(vector graphics) 1.1.4矢量图形的用途 ①计算机辅助绘图(CAD)程序. ②设 ...
- Openresty最佳案例 | 第4篇:OpenResty常见的api
转载请标明出处: http://blog.csdn.net/forezp/article/details/78616660 本文出自方志朋的博客 获取请求参数 vim /usr/example/exa ...
- Django-rest-framework(三)view and viewsets使用
DRF 中有多种view和viewsets,我整理了一下,如下图所示,接下来,我们分别了解下view,viewsets. APIView 所有的view,viewsets都是继承APIView,而AP ...
- python之selectors
selectors是select模块的包装器,ptython文档建议大部分情况使用selectors而不是直接使用selectors 样例代码如下 # -*- coding: utf-8 -*- __ ...
- 快速排序_C语言_数组
快速排序_C语言_数组 #include <stdio.h> void quickSort(int *, int, int); int searchPos(int *, int, int) ...
- JavaScript-语法专题
一.数据类型的转换 概述 JavaScript是一种动态语言,变量没有类型限制,可以随时赋予任意值 强制转换:主要是值Number(),String(),Boolean三个函数 Number函数,可以 ...
- C++求值顺序
<C++Primer5th>中文版第124页 C++语言没有明确规定大多数二元运算符的求值顺序, 给编译器优化留下了余地. 这种策略实际上是在代码生成效率和程序潜在缺陷之间进行了权衡,这个 ...
- C++指针数组,二级指针和函数指针的练习
1.编一程序,将字符串“Hello,C++!”赋给一个字符数组, 然后从第一个字母开始间隔地输出该串(请用指针完成). 代码如下 #include<iostream> #include&l ...
- Vscode配置C++运行环境(2019/1//11更)并加入bits/stdc++.h头文件
因为重装系统,以前配置好的c++环境又没了.所以有要配置一遍. 1 下载mingw64或minw, 配置好环境变量:C://mingw64//bin; 在cmd下用g++ -v验证是否成功. 2. ...
- 出现java.lang.NoSuchMethodError错误的原因
作为Java开发者我们都遇到过java.lang.NoSuchMethodError错误,究其根源,是JVM的"双亲委托模型"引发的问题.如果在类路径下放置了多个不同版本的类包,如 ...