poj2516 最小费用流
来源:互联网 发布:书安 网络尖刀 编辑:程序博客网 时间:2024/05/02 01:23
如题:http://poj.org/problem?id=2516
Description
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
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
Sample Input
1 3 3 1 1 10 1 11 2 21 0 11 2 31 1 12 1 11 1 132200 0 0
Sample Output
4-1
Source
题意:有M个供应点,N个零售商,K种商品,给出N个零售商K种商品分别需要的数量和M个供应点K种商品分别的数量,然后给出K个矩阵,第i个矩阵第j行k列表示每一单位的第i种商品从k提供商到j零售商需要的花费。要求输出最小总花费。
思路:最小费用流建立K个图处理K次,(1《i《k)每次从0到M个供应商建立权值为拥有第i种产品的数量,从M个供应商到M+j表示从供应商到零售商j建立一条拥有i产品的数量
和花费的边,然后零售商到汇点(N+M+1)建立需要i产品数量的边。用队列优化的bellman_ford每次求出一条最短,然后计算流,一共K次。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define MAX 200
#define INF 0x0fffffff
#define min(a,b)(a<b?a:b)
int N,M,K;
int need[MAX][MAX]; //need[i][j] i客户需要j产品的数量
int hav[MAX][MAX]; //hav[i][j] 提供点i有j产品的数量
int money[MAX][MAX][MAX]; //money[i][j][k] 将i产品从k运送到j客户需要的钱
int sum_hav[MAX];
int sum_need[MAX];
int cap[MAX][MAX];
int cost[MAX][MAX];
int flow[MAX][MAX];
int pre[MAX];
int dist[MAX];
void spfa(int s,int t)
{
int i;
queue<int>que;
for(i=0;i<=t;i++)
dist[i]=INF;
int inq[MAX]={0};
memset(pre,-1,sizeof(pre));
dist[s]=0;
que.push(s);
inq[s]=1;
while(!que.empty())
{
int u=que.front();
que.pop();
inq[u]=0;
for(i=0;i<=t;i++)
if(cap[u][i]>flow[u][i]&&dist[i]>dist[u]+cost[u][i])
{
dist[i]=dist[u]+cost[u][i];
pre[i]=u;
if(!inq[i])
{
inq[i]=1;
que.push(i);
}
}
}
}
int min_flow_cost(int s,int t)
{
memset(flow,0,sizeof(flow));
int v;
int res=0;
while(1)
{
spfa(s,t);
if(pre[t]==-1)
break;
int d=INF;
for(v=t;v!=s;v=pre[v])
{
d=min(d,cap[pre[v]][v]-flow[pre[v]][v]);
}
res+=d*dist[t];
for(v=t;v!=s;v=pre[v])
{
flow[pre[v]][v]+=d;
flow[v][pre[v]]-=d;
}
}
return res;
}
int main()
{
// freopen("C:\\1.txt","r",stdin);
while(~scanf("%d%d%d",&N,&M,&K))
{
if(!N&&!M&&!K)
break;
int i,j,k;
int st=0,ed=N+M+1;
memset(sum_hav,0,sizeof(sum_hav));
memset(sum_need,0,sizeof(sum_need));
for(i=1;i<=N;i++)
for(j=1;j<=K;j++)
{
scanf("%d",&need[i][j]);
sum_need[j]+=need[i][j];
}
for(i=1;i<=M;i++)
for(j=1;j<=K;j++)
{
scanf("%d",&hav[i][j]);
sum_hav[j]+=hav[i][j];
}
for(i=1;i<=K;i++)
for(j=1;j<=N;j++)
for(k=1;k<=M;k++)
scanf("%d",&money[i][j][k]);
int flag=0;
for(i=1;i<=K;i++)
if(sum_hav[i]<sum_need[i])
{
printf("-1\n");
flag=1;
break;
}
if(flag)
continue;
int flow=0;
for(i=1;i<=K;i++)
{
memset(cap,0,sizeof(cap));
memset(cost,0,sizeof(cost));
for(j=1;j<=M;j++)
for(k=1;k<=N;k++)
{
cap[j][k+M]=hav[j][i];
cost[j][k+M]=money[i][k][j];
cost[k+M][j]=-cost[j][k+M];
}
for(j=1;j<=M;j++)
cap[st][j]=hav[j][i];
for(j=1;j<=N;j++)
cap[j+M][ed]=need[j][i];
flow+=min_flow_cost(st,ed);
}
printf("%d\n",flow);
}
return 0;
}
- poj2516 最小费用流
- 【POJ2516】【最小费用流】
- poj2516 最小费用最大流
- poj2516 最小费用最大流
- poj2516 最小费用最大流
- 最小费用最大流poj2516
- POJ2516 Minimum Cost 最小费用最大流
- POJ2516--Minimum Cost最小费用最大流
- poj2516----最小费用流(模版+构图)
- POj2516 Minimum Cost 最小费用最大流
- POJ2516-Minimum Cost 最小费用最大流
- poj2516 minimum cost 最小费用流
- poj2516(最小费用最大流模版)
- 最小费用最大流粗解 poj2516
- POJ2516 Minimum Cost 最大流最小费用典型题目
- poj2516-经典最小费用最大流-有点难度
- (最小费用最大流)POJ2516 Minimum Cost
- poj2516——Minimum Cost(最小费用最大流)
- Ubuntu_文件夹名字转化成英文
- js校验表单后提交表单的三种方法总结【转载】
- oc 文件操作,查看目录下所有文件包括子文件夹内包含的所有文件,循环遍历递归
- IIS发布网站后,本机可访问局域网内其他机器不可访问
- select redio 只读 技巧
- poj2516 最小费用流
- 上下左右居中的方法总结
- 使用GRUB2制作U盘PE启动盘
- thinkphp之视图总结
- C# 中的委托和事件
- 认知
- 如何讲解自己开发的程序
- SqlServer 全文索引创建及测试
- RWTHLM 源码分析(一)之词库组织