题目链接:http://poj.org/problem?id=2516

解题思路:

  最小费用最大流,这个没什么疑问。但此题小难点在于读题,大难点在于建图。

  首先,供应量小于需求量的时候直接输出“-1”。

  供大于或等于求的情况,一开始我将每个供应商和每个购买人都拆成K个点,将所有供应商的点和超级源点相连,流量限制为库存量,费用为0;将所有购买人的点和超级汇点相连,流量限制为购买量,费用为0;而购买方和供应方之间的连线的流量限制则为inf,费用如题目中给出的。但是这种建图方式一直T......一度绝望到以为我的模板有问题,修修补补了半天,还是T......上网查了题解,发现大家的建图方式跟我不一样:大家都是把根据K种商品,建K个图逐一求最小费用最大流,答案就是K个图的最小费用之和。稍微改了一下,AC.......醉........至于为什么........我也不太懂,容我明天去问问师兄。

AC代码:

 #include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std; const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct rec {
int from, to, cost, cap;
}r[][];
struct Edge {
int to, next, cap, flow, cost;
}edge[MAXM];
int head[MAXN], tol;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N;
void init(int n) {
N = n;
tol = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int cap, int cost) {
edge[tol].to = v;
edge[tol].cap = cap;
edge[tol].cost = cost;
edge[tol].flow = ;
edge[tol].next = head[u];
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = ;
edge[tol].cost = -cost;
edge[tol].flow = ;
edge[tol].next = head[v];
head[v] = tol++;
}
bool spfa(int s, int t) {
queue<int>q;
for (int i = ; i < N; i++) {
dis[i] = INF;
vis[i] = false;
pre[i] = -;
}
dis[s] = ;
vis[s] = true;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for (int i = head[u]; i != -; i = edge[i].next) {
int v = edge[i].to;
if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost){
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
if (pre[t] == -) return false;
else return true;
}
int minCostMaxflow(int s, int t, int &cost){
int flow = ;
cost = ;
while (spfa(s, t)) {
int Min = INF;
for (int i = pre[t]; i != -; i = pre[edge[i ^ ].to]) {
if (Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
}
for (int i = pre[t]; i != -; i = pre[edge[i ^ ].to]) {
edge[i].flow += Min;
edge[i ^ ].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
}
int sup[][], buy[][];
int main() {
int N, M, K;
int need[], have[];
while (scanf("%d%d%d", &N, &M, &K) == && (N || M || K)) {
memset(need, , sizeof(need));
memset(have, , sizeof(have));
int c;
for (int i = ; i <= N; i++) {
for (int j = ; j <= K; j++) {
scanf("%d", &c);
need[j] += c;
buy[j][i] = c;
}
}
for (int i = ; i <= M; i++) {
for (int j = ; j <= K; j++) {
scanf("%d", &c);
have[j] += c;
sup[j][i] = c;
}
}
bool yes = true;
for (int j = ; j <= K; j++) {
if (have[j]<need[j]) yes = false;
} int ans = ;
for (int k = ; k <= K; k++) {
if (yes)
init(N + M + );
for (int i = ; i <= N; i++) {
for (int j = ; j <= M; j++) {
scanf("%d", &c);
if (yes)
addedge(j, M + i, INF, c);
}
}
if (yes) {
for (int i = ; i <= M; i++)
addedge(, i, sup[k][i], );
for (int i = ; i <= N; i++)
addedge(M + i, N + M + , buy[k][i], );
int cost;
minCostMaxflow(, N + M + , cost);
ans += cost;
}
}
if (!yes)
printf("-1\n");
else
printf("%d\n", ans);
}
return ;
}

POJ2516的更多相关文章

  1. 【POJ2516】Minimum Cost

    [POJ2516]Minimum Cost 题意:有N个收购商.M个供应商.K种物品.对于每种物品,每个供应商的供应量和每个收购商的需求量已知.每个供应商与每个收购商之间运送该物品的运费已知.求满足收 ...

  2. POJ2516 Minimum Cost —— 最小费用最大流

    题目链接:https://vjudge.net/problem/POJ-2516 Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Tota ...

  3. POJ-2516(最小费用最大流+MCMF算法)

    Minimum Cost POJ-2516 题意就是有n个商家,有m个供货商,然后有k种商品,题目求的是满足商家的最小花费供货方式. 对于每个种类的商品k,建立一个超级源点和一个超级汇点.每个商家和源 ...

  4. POJ2516 Minimum Cost(最小费用最大流)

    一开始我把每个店主都拆成k个点,然后建图..然后TLE.. 看题解= =哦,愚钝了,k个商品是独立的,可以分别跑k次最小费用最大流,结果就是k次总和.. #include<cstdio> ...

  5. poj-2516(最小费用流)

    题意:有n个商店,每个商店有k种货物,每个货物需要a[n][k]个,有m个仓库,每个仓库也有k种货物,每个货物有b[m][k]个,然后k个矩阵,每个矩阵都是n*m的,第i行第j列表示从仓库j到商店i每 ...

  6. POJ2516 Minimum Cost【最小费用最大流】

    题意: 有N个客户,M个仓库,和K种货物.已知每个客户需要每种货物的数量,每个仓库存储每种货物的数量,每个仓库运输各种货物去各个客户的单位费用.判断所有的仓库能否满足所有客户的需求,如果可以,求出最少 ...

  7. POJ2516:Minimum Cost(最小费用最大流)

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 19088   Accepted: 6740 题目链 ...

  8. 最小费用最大流粗解 poj2516

    最小费用最大流,一般解法如下: 在流量基础上,每条边还有权费用,即单位流量下的所需费用.在最大流量下,求最小费用.解法:在最大流算法基础上,每次按可行流增广改为每次用spfa按最小费用(用单位费用)增 ...

  9. poj-2516.minimum cost(k次费用流)

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 19883   Accepted: 7055 Des ...

  10. 网络流强化-POJ2516

    k种货物分开求解最小费用最大流,主要减少了寻找最短路的时间. #include<queue> #include<cstdio> #include<cstring> ...

随机推荐

  1. VulnHub靶场学习_HA: Chanakya

    HA-Chanakya Vulnhub靶场 下载地址:https://www.vulnhub.com/entry/ha-chanakya,395/ 背景: 摧毁王国的策划者又回来了,这次他创造了一个难 ...

  2. Linux中的常用快捷键

    tab 命令或路径补全键,linux里面最有用的快捷键,如果tab不到路径或命令,就代表没有这个路径或者命令,还有可能是权限不对 ctrl+c 终止当前任务命令或程序 ctrl+d 退出当前用户环境, ...

  3. ffmpeg+SDL2实现的音频播放器V2.0(无杂音)

    1. 前言 目前为止,学习了并记录了ffmpeg+SDL2显示视频以及事件(event)的内容. 这篇中记录ffmpeg+SDL2播放音频,没加入事件处理. 接下来加入事件处理并继续学习音视频同步,再 ...

  4. 基于国内某云的 Domain Fronting 技术实践

    发布时间:2019-12-16 11:30:53 一.简介 Domain Fronting,中文译名 “域前置” 或 “域名前置”,是一种用于隐藏真实C2服务器IP且同时能伪装为与高信誉域名通信的技术 ...

  5. STL 训练 POJ - 1862 Stripies

    Description Our chemical biologists have invented a new very useful form of life called stripies (in ...

  6. 数学--数论--HDU1825(积性函数性质+和函数公式+快速模幂+非互质求逆元)

    As we all know, the next Olympic Games will be held in Beijing in 2008. So the year 2008 seems a lit ...

  7. POJ 3267为什么优先队列超时,DP就能过,难过

    The Cow Lexicon Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 11846 Accepted: 5693 Desc ...

  8. Redis为什么是单线程的

    一.前言   最近在学习Redis,这篇文章就来简单聊聊一道常考的面试题--Redis为什么是单线程的.废话不多说,直接开始吧. 二.正文 2.1 为什么需要多线程   首先,现在的CPU一般都是由多 ...

  9. XCTF练习题-WEB-webshell

    XCTF练习题-WEB-webshell 解题步骤: 1.观察题目,打开场景 2.根据题目提示,这道题很有可能是获取webshell,再看描述,一句话,基本确认了,观察一下页面,一句话内容,密码为sh ...

  10. P2765 魔术球问题 网络流二十四题重温

    P2765 魔术球问题 知识点::最小点覆盖 这个题目要拆点,这个不是因为每一个球只能用一次,而是因为我们要求最小点覆盖,所以要拆点来写. 思路: 首先拆点,然后就是开始建边,因为建边的条件是要求他们 ...