您的位置:首页 > 其它

E - Minimum Cost - POJ 2516(最小费)

2015-08-09 18:41 423 查看
题目大意:N个客户,M个供货商,K种商品,现在知道每个客户对每种商品的需求量,也知道每个供货商每种商品的持有量,和供货商把一种商品运送到每个客户的单位花费。现在想知道如果能满足所有客户的最小花费是多少,如果不能满足输出 -1输入详解:(图片引用源自/article/1968980.html)。#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<math.h>
using namespace std;

const int MAXN = 105;
const int oo = 1e9+7;

struct Graph{int cost, flow;}G[MAXN][MAXN];
int need[MAXN][MAXN];///客户对每种商品的需求量
int have[MAXN][MAXN];///供货商对每种商品的持有量

bool spfa(int pre[], int start, int End)
{
stack<int> sta; sta.push(start);
int i, u, dist[MAXN], instack[MAXN]={0};

for(i=1; i<=End; i++)
dist[i] = oo;
dist[start] = 0;

while(sta.size())
{
u = sta.top();sta.pop();
instack[u] = false;

for(i=1; i<=End; i++)
{
if(G[u][i].flow && dist[i] > dist[u]+G[u][i].cost)
{
dist[i] = dist[u] + G[u][i].cost;
pre[i] = u;

if(instack[i] == false)
{
instack[i] = true;
sta.push(i);
}
}
}
}

return dist[End] == oo ? false : true;
}
int MinCost(int start, int End, int needFlow)
{
int i, MaxFlow=0, cost=0, pre[MAXN]={0};

while(spfa(pre, start, End) == true)
{
int MinFlow = oo;

for(i=End; i!=start; i=pre[i])
MinFlow = min(MinFlow, G[pre[i]][i].flow);
for(i=End; i!=start; i=pre[i])
{
int k = pre[i];
G[k][i].flow -= MinFlow;
G[i][k].flow += MinFlow;
cost += MinFlow * G[k][i].cost;
}

MaxFlow += MinFlow;
}

if(MaxFlow != needFlow)
cost = -1;

return cost;
}

int main()
{
int N, M, K;

while(scanf("%d%d%d", &N, &M, &K), N+M+K)
{
int i, j, k, x, needCost=0;

for(i=1; i<=N; i++)
for(j=1; j<=K; j++)
{///输入客户i对第j种商品的需求量
scanf("%d", &need[i][j]);
}

for(i=1; i<=M; i++)
for(j=1; j<=K; j++)
{///供货商i对第j种商品的持有量
scanf("%d", &have[i][j]);
}

bool ok = true;

for(k=1; k<=K; k++)
{///第k种商品

memset(G, 0, sizeof(G));

for(i=1; i<=N; i++)
for(j=1; j<=M; j++)
{///客户所在的区间为 M~N+M
scanf("%d", &x);
G[j][M+i].cost = x;
G[M+i][j].cost = -x;
G[j][M+i].flow = oo;
}

if(ok == true)
{
int start = M+N+1, End = start+1;
int needFlow = 0;///需要第k种商品的量

for(i=1; i<=M; i++)
{///建立源点与供货商间的关系
G[start][i].flow = have[i][k];
}
for(i=1; i<=N; i++)
{///建立客户与汇点之间的关系
G[M+i][End].flow = need[i][k];
needFlow += need[i][k];
}

int cost = MinCost(start, End, needFlow);

if(cost == -1)
ok = false;
else
needCost += cost;
}
}

if(ok == false)
needCost = -1;
printf("%d\n", needCost);
}

return 0;
}View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: