Description

Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area there are N shopkeepers (marked from 1 to N) which stocks goods from him.Dearboy has M supply places (marked from 1 to M), each provides K different kinds of goods (marked from 1 to K). Once shopkeepers order goods, Dearboy should arrange which supply place provide how much amount of goods to shopkeepers to cut down the total cost of transport.

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

The input consists of multiple test cases. The first line of each test case contains three integers N, M, K (0 < N, M, K < 50), which are described above. The next N lines give the shopkeepers' orders, with each line containing K integers (there integers are belong to [0, 3]), which represents the amount of goods each shopkeeper needs. The next M lines give the supply places' storage, with each line containing K integers (there integers are also belong to [0, 3]), which represents the amount of goods stored in that supply place.

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

For each test case, if Dearboy can satisfy all the needs of all the shopkeepers, print in one line an integer, which is the minimum cost; otherwise just output "-1".

题目大意: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(最小费用流)的更多相关文章

  1. POJ 2516 Minimum Cost 最小费用流 难度:1

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 13511   Accepted: 4628 Des ...

  2. 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个 ...

  3. POJ 2516 Minimum Cost (网络流,最小费用流)

    POJ 2516 Minimum Cost (网络流,最小费用流) Description Dearboy, a goods victualer, now comes to a big problem ...

  4. Poj 2516 Minimum Cost (最小花费最大流)

    题目链接: Poj  2516  Minimum Cost 题目描述: 有n个商店,m个仓储,每个商店和仓库都有k种货物.嘛!现在n个商店要开始向m个仓库发出订单了,订单信息为当前商店对每种货物的需求 ...

  5. POJ 2516 Minimum Cost (最小费用最大流)

    POJ 2516 Minimum Cost 链接:http://poj.org/problem?id=2516 题意:有M个仓库.N个商人.K种物品.先输入N,M.K.然后输入N行K个数,每一行代表一 ...

  6. POJ 2516 Minimum Cost (费用流)

    题面 Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area ...

  7. POJ - 2516 Minimum Cost 每次要跑K次费用流

    传送门:poj.org/problem?id=2516 题意: 有m个仓库,n个买家,k个商品,每个仓库运送不同商品到不同买家的路费是不同的.问为了满足不同买家的订单的最小的花费. 思路: 设立一个源 ...

  8. POJ 2516 Minimum Cost(拆点+KM完备匹配)

    题目链接:http://poj.org/problem?id=2516 题目大意: 第一行是N,M,K 接下来N行:第i行有K个数字表示第i个卖场对K种商品的需求情况 接下来M行:第j行有K个数字表示 ...

  9. POJ 2516 Minimum Cost [最小费用最大流]

    题意略: 思路: 这题比较坑的地方是把每种货物单独建图分开算就ok了. #include<stdio.h> #include<queue> #define MAXN 500 # ...

随机推荐

  1. 匿名union

    #include <stdio.h> enum node_type{    t_int,t_double}; struct node{    enum node_type type;   ...

  2. SpringBoot非官方教程 | 第十五篇:Springboot整合RabbitMQ

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot15-rabbitmq/ 本文出自方志朋的博客 这 ...

  3. 跨交换机的VLAN划分实验

    实验涉及命令以及知识补充 大部分命令和上一篇相同,本篇介绍不同的收获. 上一篇链接: https://www.cnblogs.com/Coeus-P/p/9122462.html 退出命令 ctrl+ ...

  4. iOS | Swift图片剪切圆角

    我们在IOS开发中,时常需要将一些原本是方形的图片剪切成圆形或者边框是曲线的样子,表现得活泼生动一些. 注意:因为最近在尝试用Swiftl开发,所以这里的语言使用的就是Swift,OC的语法也是相近的 ...

  5. iOS之UITextField输入错误的震动动画

    //左右震动效果 - (void)shake:(UIView *)view { CGRect frame = view.frame; CAKeyframeAnimation *shakeAnimati ...

  6. vue入门:实现图片点击切换

    1.实现功能 2.目录结构 3.代码 <!DOCTYPE html> <html lang="en"> <head> <meta char ...

  7. Lucene的原理和应用

    随着互联网的迅速普及与发展,网络舆论对社会生活的影响力越来越大, 网络口碑研究也逐渐形成一个新兴行业.有效的网络口碑研究,需要全方位地倾听网民的声音. 信息检索技术的应用,有效地提高了网络口碑研究的工 ...

  8. django+xadmin在线教育平台(十七)

    8-1 课程列表 拷贝课程列表页到template目录 创建课程相关的urls.py Mxonline2/urls.py中声明包含到course的url中: # 课程app的url配置 url(r&q ...

  9. PHP一些常用魔术方法

    魔术方法                          调用方法                                     作用__set                   有两个 ...

  10. Python入门学习笔记4:他人的博客及他人的学习思路

    看其他人的学习笔记,可以保证自己不走弯路.并且一举两得,即学知识又学方法! 廖雪峰:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958 ...