poj 2516 Minimum Cost(最小费最大流)

poj 2516 Minimum Cost

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”.

Sample Input

1 3 3

1 1 1

0 1 1

1 2 2

1 0 1

1 2 3

1 1 1

2 1 1

1 1 1

3

2

20

0 0 0

Sample Output

4

-1

题目大意:输入数据。

此图来自:ζёСяêτ - 小優YoU

在已知这些信息之后,求供货商能否满足商店的需求,不能输出“-1”,能的话输出供货商给商家发货的最小费用。

解题思路:一开是看完这道题目,觉得无从下手,这图太复杂了。后来才想到其实不一定只能用一张图,这题可以拆成k张图。首先要判断一下,供货商能否满足商家的货物需求,不能的话输出-1,能的话,继续建图。每张图设置一个超级源点连向所有的供货商,容量为该供货商第i种商品的存货(1<=i<=k),费用为0;每个供货商都连向所有的商店,容量为INF,费用为该供货商给对应商店发送i号货物的花费;最后设置一个超级汇点,使所有商店连向该汇点,容量为该商店的需求,费用为0;。然后求k次最小费,把k次的最小费加起来,就是最终答案。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;

const int N = 500;
const int M = 50005;
const int OF = 60;
const int FIN = 400;
const int INF = 0x3f3f3f3f;
int shop[N][N], sup[N][N], good[N][N][N], rec[N];
typedef long long ll;
int n, m, k, s, t, flag;
int pre[N], inq[N];
ll a[N], d[N];

struct Edge{
    int from, to;
    ll cap, flow;
    ll cos;
};

vector<Edge> edges;
vector<int> G[M];

void init() {
    for (int i = 0; i < M; i++) G[i].clear();
    edges.clear();
}

void addEdge(int from, int to, ll cap, ll flow, ll cos) {
    edges.push_back((Edge){from, to, cap, 0, cos});
    edges.push_back((Edge){to, from, 0, 0, -cos});
    int m = edges.size();
    G[from].push_back(m - 2); G[to].push_back(m - 1);
}

void input() {
    memset(rec, 0, sizeof(rec));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < k; j++) {
            scanf("%d", &shop[i][j]);
            rec[j] += shop[i][j];
        }
    }
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < k; j++) {
            scanf("%d", &sup[i][j]);
            rec[j] -= sup[i][j];
        }
    }
    for (int i = 0; i < k; i++) {
        if (rec[i] > 0) flag = 0;
    }
    for (int l = 0; l < k; l++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                scanf("%d", &good[i][j][l]);
            }
        }
    }
}

int BF(int s, int t, ll& flow, ll& cost) {
    queue<int> Q;
    memset(inq, 0, sizeof(inq));
    memset(a, 0, sizeof(a));
    memset(pre, 0, sizeof(pre));
    for (int i = 0; i < N; i++) d[i] = INF;
    d[s] = 0;
    a[s] = INF;
    inq[s] = 1;
    int flag = 1;
    pre[s] = 0;
    Q.push(s);
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        inq[u] = 0;
        for (int i = 0; i < G[u].size(); i++) {
            Edge &e = edges[G[u][i]];
            if (e.cap > e.flow && d[e.to] > d[u] + e.cos) {
                d[e.to] = d[u] + e.cos;
                a[e.to] = min(a[u], e.cap - e.flow);
                pre[e.to] = G[u][i];
                if (!inq[e.to]) {
                    inq[e.to] = 1;
                    Q.push(e.to);
                }
            }
        }
        flag = 0;
    }
    if (d[t] == INF) return 0;
    flow += a[t];
    cost += (ll)d[t] * (ll)a[t];
    for (int u = t; u != s; u = edges[pre[u]].from) {
        edges[pre[u]].flow += a[t];
        edges[pre[u]^1].flow -= a[t];
    }
    return 1;
}

int MCMF(int s, int t, ll& cost) {
    ll flow = 0;
    cost = 0;
    while (BF(s, t, flow, cost));
    return flow;
}

void solve() { //求k次最小费
    ll ans = 0;
    for (int K = 0; K < k; K++) {
        init();
        for (int i = 1; i <= m; i++) {
            addEdge(s, i, sup[i - 1][K], 0, 0);
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                addEdge(j, i + OF, INF, 0, good[i - 1][j - 1][K]);
            }
        }
        for (int i = 1; i <= n; i++) {
            addEdge(i + OF, t, shop[i - 1][K], 0, 0);
        }
        ll cost;
        MCMF(s, t, cost);
        ans += cost;
    }
    printf("%lld\n", ans);
}

int main() {
    while (scanf("%d %d %d", &n, &m, &k) == 3) {
        if (!n && !m && !k) break;
        flag = 1;
        s = 0, t = FIN;
        input();
        if (!flag) {
            printf("-1\n");
            continue;
        }
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-25 17:38:30

poj 2516 Minimum Cost(最小费最大流)的相关文章

POJ 2516 Minimum Cost(网络流之费用流)

题目地址:POJ 2516 我晕啊...这题一上来就想到了对每种货物分开求..但是马上就放弃了..感觉这样求50次费用流太耗时..后来就果断拆点,拆了好长时间,一直TLE..即使降到了2600个点也TLE..然后又想起了这个分开求的方法,又突然觉得100个点的费用流几乎不费什么时间..最多也只是求50次而已,还是可以试试的..于是一试居然还真过了... 说到这里,思路应该已经知道了吧.就是对每种货物分开求,因为每种货物是相互独立的.每一次的建图思路就是: 源点与供应商连边,流量权值为供应商这种货

POJ 2516 Minimum Cost(最小费用最大流,坑题)

题目链接:http://poj.org/problem?id=2516 题意:有N个店,M个供货商,K种商品.已知供货商的仓库里每种商品的数量以及每种商品运送到每个店的费用,每个店铺对各种商品的需求数量,求最少话费. Input  第一行:N,M,K. 然后1 - N行,每行 K列 ,第I行第J个数代表 第I个店铺 需要第J种物品多少件. 然后 N+1 - M行  ,每行 K列 , 第I行第J个数代表 第I个供货商 有第J种物品多少件. 然后是K个矩阵  ,每个N行M列,第ji个矩阵的第i行第j

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

题目链接: Poj  2516  Minimum Cost 题目描述: 有n个商店,m个仓储,每个商店和仓库都有k种货物.嘛!现在n个商店要开始向m个仓库发出订单了,订单信息为当前商店对每种货物的需求量.不同的商店从不同的仓库购买不同货物花费不同,问是不是能满足所有商店的要求,如果能商店花费总和最小为多少? 解题思路: 简单的费用流,要跑K次最小花费最大流,每次只对一种货物建图跑费用流.每次建图以0为源点, [1,m]为仓库, [m+1, n+m]为商店, n+m+1为汇点.0与[1,m]连边,

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

Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K       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

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

POJ 2516 Minimum Cost 链接:http://poj.org/problem?id=2516 题意:有M个仓库,N个商人,K种物品.先输入N,M,K.然后输入N行K个数,每一行代表一个商人要购买的物品,其中K个数分别表示要购买的每件商品数.然后是M行K个数,每行表示仓库里的情况,其中K个数分别每种物品的库存量.接下来是K个矩阵,每个矩阵为N*M,分别表示第K种物品从M个仓库运到第N个商人的花费.问能否合理安排,使得花费最少,如果不行就输出-1. 思路: 一开始的时候,竟然构造了

poj 2516 Minimum Cost 【最小费用最大流】

题目:poj 2516 Minimum Cost 题意:有 n 个商店,k种物品和 m 个供货商,让你求进满足商店需求的货物的最小花费? 有必要说一下输入数据. 首先n ,k ,m 然后是一个n*m的矩阵,n个商店对每种货物的需求,表示第 i 个商店需要第 j 种货物 x个 然后是m * k 的矩阵,m个供货商可以供k种货物的数量,表示第 i 个供货商 提供第 j 中货物 x 个 接下来是 k 个 n * m 的矩阵,表示第 i 个货物,由 k 供应商发货给 j 商店的价格x (注意如果供不应求

POJ 2516 Minimum Cost(费用流)

POJ 2516 Minimum Cost 题目链接 题意:转一篇题意吧..感觉写的很详细了,優YoU http://blog.csdn.net/lyy289065406/article/details/6742534 思路:一开始是把所有商家的每种物品和所有供应商所有物品连边跑费用流,结果TLE了,因为这样建出来的图,边数会非常的庞大 那么其实转化一下思路,每种物品之间是不会互相影响的,那么把每种物品求出来后,累加起来就是答案了,然后注意这题数据要读完,直接判断错没读完数据就会WA 代码: #

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

题目链接:http://poj.org/problem?id=2516 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 (mar

POJ 2516 Minimum Cost

Minimum Cost Time Limit: 4000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 251664-bit integer IO format: %lld      Java class name: Main Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In hi