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

一开始我把每个店主都拆成k个点,然后建图。。然后TLE。。

看题解= =哦,愚钝了,k个商品是独立的,可以分别跑k次最小费用最大流,结果就是k次总和。。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<algorithm>
  5 using namespace std;
  6 #define INF (1<<30)
  7 #define MAXN 111
  8 #define MAXM 111*111*2
  9 struct Edge{
 10     int u,v,cap,cost,next;
 11 }edge[MAXM];
 12 int head[MAXN];
 13 int NV,NE,vs,vt;
 14
 15 void addEdge(int u,int v,int cap,int cost){
 16     edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost;
 17     edge[NE].next=head[u]; head[u]=NE++;
 18     edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost;
 19     edge[NE].next=head[v]; head[v]=NE++;
 20 }
 21 bool vis[MAXN];
 22 int d[MAXN],pre[MAXN];
 23 bool SPFA(){
 24     for(int i=0;i<NV;++i){
 25         vis[i]=0;
 26         d[i]=INF;
 27     }
 28     vis[vs]=1;
 29     d[vs]=0;
 30     queue<int> que;
 31     que.push(vs);
 32     while(!que.empty()){
 33         int u=que.front(); que.pop();
 34         for(int i=head[u]; i!=-1; i=edge[i].next){
 35             int v=edge[i].v;
 36             if(edge[i].cap && d[v]>d[u]+edge[i].cost){
 37                 d[v]=d[u]+edge[i].cost;
 38                 pre[v]=i;
 39                 if(!vis[v]){
 40                     vis[v]=1;
 41                     que.push(v);
 42                 }
 43             }
 44         }
 45         vis[u]=0;
 46     }
 47     return d[vt]!=INF;
 48 }
 49 int MCMF(){
 50     int res=0;
 51     while(SPFA()){
 52         int flow=INF,cost=0;
 53         for(int u=vt; u!=vs; u=edge[pre[u]].u){
 54             flow=min(flow,edge[pre[u]].cap);
 55         }
 56         for(int u=vt; u!=vs; u=edge[pre[u]].u){
 57             edge[pre[u]].cap-=flow;
 58             edge[pre[u]^1].cap+=flow;
 59             cost+=flow*edge[pre[u]].cost;
 60         }
 61         res+=cost;
 62     }
 63     return res;
 64 }
 65
 66 int n,m,k,mat[55][55][55],to[55][55],from[55][55];
 67 bool isOK(int *need,int *supply){
 68     for(int i=0; i<k; ++i) if(need[i]>supply[i]) return 0;
 69     return 1;
 70 }
 71 int main(){
 72     int a;
 73     while(~scanf("%d%d%d",&n,&m,&k) && (n||m||k)){
 74         int sum=0;
 75         int supply[55]={0},need[55]={0};
 76         for(int i=0; i<n; ++i){
 77             for(int j=0; j<k; ++j){
 78                 scanf("%d",&to[i][j]);
 79                 need[j]+=to[i][j];
 80             }
 81         }
 82         for(int i=0; i<m; ++i){
 83             for(int j=0; j<k; ++j){
 84                 scanf("%d",&from[i][j]);
 85                 supply[j]+=from[i][j];
 86             }
 87         }
 88         for(int z=0; z<k; ++z){
 89             for(int x=0; x<n; ++x){
 90                 for(int y=0; y<m; ++y) scanf("%d",&mat[z][x][y]);
 91             }
 92         }
 93         if(!isOK(need,supply)){
 94             puts("-1");
 95             continue;
 96         }
 97
 98         vs=n+m; vt=vs+1; NV=n+m+2;
 99         int res=0;
100         for(int good=0; good<k; ++good){
101             NE=0;
102             memset(head,-1,sizeof(head));
103
104             for(int i=0; i<m; ++i) addEdge(vs,i,from[i][good],0);
105             for(int i=0; i<n; ++i) addEdge(i+m,vt,to[i][good],0);
106             for(int i=0; i<n; ++i){
107                 for(int j=0; j<m; ++j) addEdge(j,i+m,INF,mat[good][i][j]);
108             }
109             res+=MCMF();
110         }
111         printf("%d\n",res);
112     }
113     return 0;
114 }
时间: 2024-10-31 00:23:20

POJ2516 Minimum Cost(最小费用最大流)的相关文章

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 (最小费用最大流)

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

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 (最小费用最大流)

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 2526 Minimum Cost【最小费用最大流】

题目链接:http://poj.org/problem?id=2516 题意: n个店主 m个供应商 k种货物 给你店主对k种货物的需求及供货商k种货物的囤货量及K种运输费用. 解法:k次费用流,分别求每种货物的费用.源点到供应点建边,店主到汇点建边,费用均为0,容量为1.然后供应点到店主建边,费用为矩阵,容量无穷大即可. 代码: /* POJ 2195 Going Home 邻接矩阵形式最小费用最大流 */ #include<stdio.h> #include<iostream>

最小费用最大流粗解 poj2516

最小费用最大流,一般解法如下: 在流量基础上,每条边还有权费用,即单位流量下的所需费用.在最大流量下,求最小费用.解法:在最大流算法基础上,每次按可行流增广改为每次用spfa按最小费用(用单位费用)增广,每次按每条边一单位费用求到达终点的最小费用(最短路),那么每次找到"最短路"(只是一条路,不是多条(dinic每次可以增广多条)),之后按这条路最大 可能流量增广(取这条路上残量最小的),直到无法增广为止.(实现细节点代码备注). 该题题意:m个供应地向n个商店供应k种物品,对于每种物

POJ--2516--Minimum Cost【最小费用最大流】

链接:http://poj.org/problem?id=2516 题意:有k种货物,n个客户对每种货物有一定需求量,有m个仓库,每个仓库里有一定数量的k种货物,然后k个n*m的矩阵,告诉从各个仓库到各个客户位置运送单位第k种货物所需的运费,问满足所有客户需求的最小费用,如满足不了所有客户,则输出-1. 思路:题目有点绕,不过多看看也就理解了.这道题算是最小费用最大流的入门题吧,建图很容易能想到,主要是存在k种货物,每条货物都要建一条路,同时处理起来不好写,而且路径也较多,不过可以对每种货物分开