POJ--2516 - Minimum Cost(最小费用最大流)
2018-01-11 17:56
399 查看
这道题其实不算难,是个经典的基础题目,题目并不是很容易理解
有n个商店,m个提供商,k种商品
接下来n行,每行有k个数字,表示这个商店需要各个物品的个数。
再接下来m行,对于每一个提供商也有k个数字,表示这个提供商拥有各个物品的个数。
然后,对于每个物品k,都有n行m列的矩阵。
i行j列表示:
从j提供商向i商店运送一个k商品的代价是多少。
判断所有的仓库能否满足所有客户的需求,如果可以,求出最少的运输总费用。
无非就是原来是一件物品,现在变为了K件物品了
那么可以一个循环,循环K次,然后每次只看一件物品
在建图的时候,用源点对供应商,流量为供应商的提供量。
供应商对商店,流量为无限
商店对汇点,流量为商店的需求量
cost就额外输入,只用记录该件物品从供应点 i 运送到商店 j 的代价,注意要反向弧也要记录
有n个商店,m个提供商,k种商品
接下来n行,每行有k个数字,表示这个商店需要各个物品的个数。
再接下来m行,对于每一个提供商也有k个数字,表示这个提供商拥有各个物品的个数。
然后,对于每个物品k,都有n行m列的矩阵。
i行j列表示:
从j提供商向i商店运送一个k商品的代价是多少。
判断所有的仓库能否满足所有客户的需求,如果可以,求出最少的运输总费用。
无非就是原来是一件物品,现在变为了K件物品了
那么可以一个循环,循环K次,然后每次只看一件物品
在建图的时候,用源点对供应商,流量为供应商的提供量。
供应商对商店,流量为无限
商店对汇点,流量为商店的需求量
cost就额外输入,只用记录该件物品从供应点 i 运送到商店 j 的代价,注意要反向弧也要记录
#include <iostream> #include <queue> #include <string.h> #include <stdio.h> using namespace std; #define INF 0x3f3f3f3f; #define MAXV 160 #define min(a,b) (a>b?b:a) int n,m,k,source,sink,maxflow,mincost; int res[MAXV][MAXV],cost[MAXV][MAXV],nn[MAXV][MAXV],mm[MAXV][MAXV]; int parent[MAXV],d[MAXV]; void spfa() { queue <int>q; int i,v; bool vis[MAXV]; memset(parent,-1,sizeof(parent)); memset(vis,false,sizeof(vis)); for(i=source; i<=sink; i++) d[i]=INF; d[source]=0; q.push(source); vis[source]=true; while(!q.empty()) { v=q.front(); q.pop(); vis[v]=false; for(i=0; i<=sink; i++) { if(res[v][i] && d[v]+cost[v][i]<d[i]) { d[i]=d[v]+cost[v][i]; parent[i]=v; if(!vis[i]) { vis[i]=true; q.push(i); } } } } } void MCMF() { int v,minflow; maxflow=0; while(1) { spfa(); //走一次最短路 if(parent[sink]==-1) break;//如果最短路没有 minflow=INF; //找出最短路径的最小增广流 v=sink; while(parent[v]!=-1) { minflow=min(minflow,res[parent[v]][v]);//将最短路的路径搜索一遍,找出最小流 v=parent[v]; } v=sink; //对增广路进行流增广 while(parent[v]!=-1) { res[parent[v]][v]-=minflow; res[v][parent[v]]+=minflow; v=parent[v]; } maxflow+=minflow; mincost+=d[sink]*minflow; //总的代价 } } void build_gragh(int x) { int i,j; memset(res,0,sizeof(res)); for(i=1; i<=n; i++) res[i][sink]=nn[i][x]; //商店指向汇点 for(i=1; i<=m; i++) res[source][i+n]=mm[i][x]; //源点指向提供商 for(i=1; i<=m; i++) //提供商对商店的流量为无限大 { for(j=1; j<=n; j++) res[i+n][j]=INF; } } int main() { int i,j,r,flag; int need[MAXV],have[MAXV]; while(scanf("%d%d%d",&n,&m,&k) && n || m || k) { memset(need,0,sizeof(need)); memset(have,0,sizeof(have)); source=0,sink=n+m+1,mincost=0; for(i=1; i<=n; i++) { for(j=1; j<=k; j++) { scanf("%d",&nn[i][j]);//nn暂时储存第i个商店K种物品的数量 need[j]+=nn[i][j];//need储存k种物品需要的总量 } } for(i=1; i<=m; i++) { for(j=1; j<=k; j++) { scanf("%d",&mm[i][j]);//mm储存每个进货点K种物品的数量 have[j]+=mm[i][j];//have储存k种物品可以提供的总量 } } flag=0; for(i=1; i<=k; i++) { if(need[i]>have[i]) //如果某种物品的需求大于提供商能够提供的物品就输出-1 { flag=1; break; } } for(r=1; r<=k; r++) //K种物品一种一种来 { memset(cost,0,sizeof(cost)); for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%d",&cost[j+n][i]); cost[i][j+n]=-cost[j+n][i]; //反向路径要设为负权值 } } if(flag) continue; //如果中途有一种物品不符合情况,那么可以直接break build_gragh(r); //建图 MCMF(); //费用流 if(need[r]>maxflow) flag=1; //比较最大流与这种物品所需要的总和 } if(flag) printf("-1\n"); else printf("%d\n",mincost); } return 0; }
相关文章推荐
- POJ 2516 Minimum Cost(最小费用最大流)
- poj2516——Minimum Cost(最小费用最大流)
- poj 2516 Minimum Cost (最小费用最大流)
- POJ 2516 Minimum Cost (最小费用最大流)
- POJ - 2516 Minimum Cost (最小费用最大流)
- POJ 2516 Minimum Cost (最小费用最大流)
- poj 2516 Minimum Cost 最小费用最大流
- POJ 2516 Minimum Cost(最小费用最大流啊)
- POJ 2516 Minimum Cost(最小费用最大流)
- 【最小费用最大流】POJ-2516 Minimum Cost
- poj 2516 Minimum Cost(最小费用最大流)
- POJ 2516 Minimum Cost (最小费用最大流)
- poj 2516 Minimum Cost 最小费用最大流
- POJ 2516 Minimum Cost(最小费用最大流)
- POJ 2516 Minimum Cost 【MCMF:最小费用最大流】
- poj 2516 Minimum Cost(最小费用最大流)
- POJ 2516 Minimum Cost【最小费用最大流】
- POJ 2516--Minimum Cost【最小费用最大流 && 经典】
- poj 2516 Minimum Cost(最小费用最大流)
- poj 2516 Minimum Cost(最小费用最大流 spfa算法求最短路)