POJ 2516 Minimum Cost 【费用流】

建模比较难想。。

#include<iostream>
#include<deque>
#include<vector>
#include<cstring>
#include<cmath>
#define INF 2e9
using namespace std;

int T,ans;

struct edge{
    int v,cap,reverse,cost;
};
vector<int> edges[1005];//邻接表
vector<edge> bian;//所有的边都存在里面

void addedge(int u,int v,int cost,int cap){//u到v一条边,再加一条反向边
    edge e;
    e.cap=cap;
    e.v=v;
    e.cost=cost;
    e.reverse=bian.size()+1;//这条边的反边将建在这条边之后(这条边建完后在bian.size()的位置)
    bian.push_back(e);
    edges[u].push_back(bian.size()-1);

    e.cap=0;
    e.v=u;
    e.cost=-cost;
    e.reverse=bian.size()-1;
    bian.push_back(e);
    edges[v].push_back(bian.size()-1);
}

int dist[1005],pre[1005];//pre[i]代表走的哪条边到的i点 

bool spfa(){
    for(int i=0;i<=T;i++) dist[i]=INF;
    for(int i=0;i<=T;i++) pre[i]=-1;

    deque<int> q;
    dist[0]=0; pre[0]=-1; q.push_back(0);
    while( !q.empty() ){
        int u = q.front(); q.pop_front();
        for(int i=0;i<edges[u].size();i++){//所有以u为起点的边的边的索引
            edge &e = bian[ edges[u][i] ];
            int v=e.v;
            if( e.cap>0 && dist[u]+e.cost<dist[v] ){
                dist[v] = dist[u]+e.cost;
                pre[v]=edges[u][i];
                q.push_back(v);
            }
        }
    }

    if(dist[T]==INF) return false;
    return true;
}

int EK(){
    int max_flow=0;
    while( spfa() ){
        //cout<<"suc"<<endl;
        int u=T,minflow=INF;//在终点位置
        while( u!=0 ){
            edge &e = bian[ pre[u] ];
            minflow=min(minflow,e.cap);
            u = bian[ e.reverse ].v;
        }
        ans+=minflow*dist[T];
        max_flow+=minflow;
        u=T;
        while( u!=0 ){
            edge &e = bian[ pre[u] ];
            e.cap-=minflow;
            bian[ e.reverse ].cap+=minflow;
            u = bian[ e.reverse ].v;
        }
    }
    return max_flow;
}

int order[55][55],supply[55][55];//order是第i个商家对第j个物品的需求  supply第i个supply对第j个物品的库存 

int main(){
    int n,m,k;        

    while(1){
        cin>>n>>m>>k;
        if(n==0 && m==0 && k==0) break;

        ans=0;

        //supply:1-M  shopkeeper:M+1 - M+N
        T = n+m+1;
        //k个物品间是相互独立的,所以等于跑k次费用流
        for(int i=1;i<=n;i++)
            for(int j=1;j<=k;j++) cin>>order[i][j];

        for(int i=1;i<=m;i++)
            for(int j=1;j<=k;j++) cin>>supply[i][j];

        bool flag=true;
        for(int k1=1;k1<=k;k1++){//k1个商品
            bian.clear();
            for(int i=0;i<=T;i++) edges[i].clear();

            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){//第j个供应商给i商店供应k商品的代价
                    int cost; cin>>cost;
                    addedge(j,m+i,cost,INF);
                }
            }
            //supply到shop解决了
            for(int i=1;i<=n;i++) addedge(m+i,T,0,order[i][k1]);//shop到汇点
            for(int i=1;i<=m;i++) addedge(0,i,0,supply[i][k1]);

            int sum=0;
            for(int i=1;i<=n;i++) sum+=order[i][k1];

            if( EK()!=sum ) flag=false;
        }
        if( flag ) cout<<ans<<endl;
        else cout<<"-1"<<endl;

    }

    return 0;
}

原文地址:https://www.cnblogs.com/ZhenghangHu/p/9531757.html

时间: 2024-11-05 21:31:19

POJ 2516 Minimum Cost 【费用流】的相关文章

POJ 2516 Minimum Cost(费用流)

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

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 我晕啊...这题一上来就想到了对每种货物分开求..但是马上就放弃了..感觉这样求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(最小费最大流)

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

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: 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