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 # ...
随机推荐
- html基础用法(上)
html的定义: html超文本标记语言,标准通用标记语言下的一个应用. “超文本”就是指页面内可以包含图片,链接,甚至音乐,程序等非文字语言. 超文本标记语言的结构包括“头”部分(head),和“主 ...
- Eslint代码规范
- DB2 SQL Error: SQLCODE = -798, SQLSTATE = 428C9
DB2 SQL Error: SQLCODE = -798, SQLSTATE = 428C9报错是因为 , 你往设置了ALWAYS自增的列里面插了初始值 . ALWAYS自增设置如下. -- 设置主 ...
- DLL DEF文件编写方法 VC++ 调用、调试DLL的方法 显式(静态)调用、隐式(动态)调用
DLL 文件编写方法: 1.建立DLL工程 2.声明.定义要导出的函数 BOOL WINAPI InitDlg( HWND hTabctrl,TShareMem* pTshare,CRect* prc ...
- A^B Mod C (51Nod - 1046 )(快速幂)
给出3个正整数A B C,求A^B Mod C. 例如,3 5 8,3^5 Mod 8 = 3. Input 3个正整数A B C,中间用空格分隔.(1 <= A,B,C <= 10^ ...
- 解决pycharm报错:AttributeError: module 'pip' has no attribute 'main'
找到pycharm安装目录下 helpers/packaging_tool.py文件,找到如下代码: def do_install(pkgs): try: import pip except Impo ...
- Excel学习路径总结
本片涉及从入门到Excel的各个方向,包含众多资料和自己学习的心得,希望您可以仔细阅之: 入门篇: 无论是软件,还是编程,最好的入门就是通过看视频来学习,视频优点为很容易看清楚,手把手教授,不容易 ...
- C语言实现二分查找
二分查找优势:比顺序查找更有效率 特点:元素按顺序排列 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include ...
- Kubernetes-Envoy(一种全新的Ingress实现方式)
Ingress 在讲Envoy之前,先介绍一下Kubernetes中Service的表现形式为IP:Port,及工作在Ingress:TCP/IP层.而对于基于HTTP的服务来说,不同的URL地址经常 ...
- MongoDB入门---简介
最近呢,刚好有一些时间,所以就学习了一下新的数据库类型MongoDB.要想了解这个MongoDB,我们首先需要了解一个概念,那就是nosql(not only sql).一下就是官方的概念: NoSQ ...