POJ2516 Minimum Cost最小费用最大流

Posted codeg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2516 Minimum Cost最小费用最大流相关的知识,希望对你有一定的参考价值。

题意:

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

思路:

最小费用最大流。先判断是否每种货物的存储总量都足够,足够的话,对每一种货物进行一次最小费用最大流求出完成这种货物运输的最小总费用,所有的总费用相加就是结果了。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
const int maxn = 110;
const int inf = 99999999;

int n, ans;
int cap[maxn][maxn], pre[maxn];
int cost[maxn][maxn], dis[maxn];
int que[maxn];
bool vis[maxn];

bool spfa()
{
    int i, head = 0, tail = 1;
    for(i = 0; i <= n; i ++){
        dis[i] = inf;
        vis[i] = false;
    }
    dis[0] = 0;
    que[0] = 0;
    while(tail != head){
        int u = que[head];
        vis[u] = true;
        for(i = 0; i <= n; i ++)
            if(cap[u][i] && dis[i] > dis[u] + cost[u][i]){
                dis[i] = dis[u] + cost[u][i];
                pre[i] = u;
                if(!vis[i]){
                    vis[i] = true;
                    que[tail ++] = i;
                    if(tail == maxn) tail = 0;
                }
            }
        vis[u] = false;
        head ++;
        if(head == maxn) head = 0;
    }
    if(dis[n] == inf) return false;
    return true;
}

void end()
{
    int i, sum = inf;
    for(i = n; i != 0; i = pre[i])
        sum = min(sum, cap[pre[i]][i]);
    for(i = n; i != 0; i = pre[i]){
        cap[pre[i]][i] -= sum;
        cap[i][pre[i]] += sum;
        ans += cost[pre[i]][i] * sum;
    }
}

int main()
{
    int N, M, K, i, j, k;
    int need[maxn][maxn], NeedK[maxn];
    int have[maxn][maxn], HaveK[maxn];
    while(cin>>N>>M>>K,N,M,K)
    {
        memset(NeedK, 0, sizeof(NeedK));
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= K; j ++){
                scanf("%d", &need[i][j]);    //  第i个客户需要第j种货物的量。
                NeedK[j] += need[i][j];      //  第j种货物总共需要的量。
            }
        memset(HaveK, 0, sizeof(HaveK));
        for(i = 1; i <= M; i ++)
            for(j = 1; j <= K; j ++){
                scanf("%d", &have[i][j]);    //  第i个仓库存储第j种货物的量。
                HaveK[j] += have[i][j];      //  第j种货物总共需要的量。
            }
        bool flag = true;
        for(i = 1; i <= K; i ++)             //  判断所有货物是否足够。
            if(NeedK[i] > HaveK[i]){
                flag = false; break;
            }
        ans = 0;
        n = N + M + 1;
        for(k = 1; k <= K; k ++){
            memset(cap, 0, sizeof(cap));
            for(i = 1; i <= N; i ++)         //  建图。
                for(j = 1; j <= M; j ++){
                    scanf("%d", &cost[j][M+i]);
                    cost[M+i][j] = -cost[j][M+i];
                    cap[j][M+i] = inf;
                }
            if(!flag) continue;
            for(i = 1; i <= M; i ++){
                cap[0][i] = have[i][k];
                cost[0][i] = cost[i][0] = 0;
            }
            for(i = 1; i <= N; i ++){
                cap[M+i][n] = need[i][k];
                cost[M+i][n] = cost[n][M+i] = 0;
            }
            while(spfa()) end();            //  最小费用最大流算法。
        }
        if(flag) cout << ans << endl;
        else cout << -1 << endl;
    }
    return 0;
}

 

以上是关于POJ2516 Minimum Cost最小费用最大流的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

Minimum Cost POJ - 2516 (模板题 spfa最小费用最大流)

Minimum Cost POJ - 2516(模板题。。没啥好说的。。)

POJ 2516 Minimum Cost (KM最优匹配)