UVA - 11613 Acme Corporation(任意流最小费用)

题目链接

Problem I
Acme Corporation

Input: Standard Input

Output: Standard Output

 

Wile E. Coyote is back. He is back in the business. The business of capturing the road runner. Being the most loyal customer to the Acme Corporation, they are hoping to do some great business with him. Although, Acme makes literally every kinds of devices, all of them has a similarity, that has been kept secret for ages. All of their products use a secret element element X (this is kept so secret that, only you and the Acme people know about this). The decision makers of the Acme Corp. has already estimated the maximum amount of element X that can be used into manufacture every month.

 

For month i, the per unit manufacturing cost of element X is mi, and at most ni units can be produced. Moreover, the selling price for element X for that month is pi. One more thing is that, element X older than Ei months can not be used. But good thing is that, they can store any amount of element X in their inventory (it's the Acme Corp, they can make anything :) ). Now, Acme Corporation wants to know how much element X should be produced and sold, to make the highest amount of profit.

 

 

 

 

Input

 

l        First line contains T, the number of test cases.

l        For each test case

u      First line contains two integers M and I, the number of months to consider and the cost of storing per unit of element X per month in the inventory.

u      Each of the next M lines describe the parameters for each month

          The ith line contains 5 integers, mi, ni, pi, si, Ei, where mi is the per unit manufacturing cost for month ini is the maximum amount that can be manufactured in this month, pi is the selling price for that month(per unit), si is the maximum amount that can be sold that month, and Ei is the maximum time,element X manufactured on month i, can be stored in the inventory. For example, if for month 1, E1 = 3, the elements produced in month 1 can be sold in months 1, 2, 3 and 4. But it can not be sold in month 5.

 

 

Output

 

For each test case, output the case number and the maximum amount of profit, Acme Corporation can make. Note that, you have to think of only M months. If any amount of element X is stored in the inventory after this period, are completely ignored. For formatting, see the sample input and output.

 

Constraints

 

l        

l        

l        

l        

 

 

 

Sample Input Output for Sample Input

1

2 2

2 10 3 20 2

10 100 7 5 2

Case 1: 2

 

 

Problem Setter: Manzurur Rahman Khan

Special Thanks: Md. Arifuzzaman Arif


题意:Acme公司生产一种X元素。给出该元素在未来M个月中每个月的单位售价,最大产量,生产成本,最大销售量,以及最大存储时间,计算公司能获得的最大利润。

题解:
这一题需要拆点,将每个月拆成入点和出点,建立源点和汇点,拆点方法以及原因可见训练指南P371,说一说通过这题得到的新的知识吧,写完这一题我才发现求最小费用最大流时并不是走那条边就花费边对应的费用,而是每个单位流量花费的费用!然后以前用的最小费用最大流板子其实很好理解,就是裸的bfs找增广路,建议看一下,然后这一题是求任意流最小费用,我看明白板子后修改了板子一个小地方就能实现这个了,修改的地方代码上有标注。另外结果是长整形,注意一下。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
const int MAXN = 200+50;
const int MAXM = MAXN*MAXN;
const ll INF = 0x3f3f3f3ffff;
struct Edge
{
    int to,next,cap,flow;
	ll cost;
}edge[MAXM];
int head[MAXN],tol;
int pre[MAXN];
ll dis[MAXN];
bool vis[MAXN];
int N;//节点总个数,节点编号从0~N-1
void init(int n)
{
    N = n;
    tol = 0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int cap,ll cost)
{
    edge[tol].to = v;
    edge[tol].cap = cap;
    edge[tol].cost = cost;
    edge[tol].flow = 0;
    edge[tol].next = head[u];
    head[u] = tol++;
    edge[tol].to = u;
    edge[tol].cap = 0;
    edge[tol].cost = -cost;
    edge[tol].flow = 0;
    edge[tol].next = head[v];
    head[v] = tol++;
}
bool spfa(int s,int t)
{
    queue<int> q;
    for(int i = 0;i < N;i++)
    {
        dis[i] = INF;
        vis[i] = false;
        pre[i] = -1;
    }
    dis[s] = 0;
    vis[s] = true;
    q.push(s);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(int i = head[u]; i != -1;i = edge[i].next)
        {
            int v = edge[i].to;
            if(edge[i].cap > edge[i].flow &&
               dis[v] > dis[u] + edge[i].cost )
            {
                dis[v] = dis[u] + edge[i].cost;
                pre[v] = i;
                if(!vis[v])
                {
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
    if(pre[t] == -1)return false;
    else if(dis[t]>=0) return false;   //修改处 
    return true;                     //修改处 
}
//返回的是最大流,cost存的是最小费用
int minCostMaxflow(int s,int t,ll &cost)
{
    int flow = 0;
    cost = 0;
    while(spfa(s,t))
    {
        int Min = 0x3f3f3f3f;
        for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
        {
            if(Min > edge[i].cap - edge[i].flow)
                Min = edge[i].cap - edge[i].flow;
        }
        for(int i = pre[t];i != -1;i = pre[edge[i^1].to])
        {
            edge[i].flow += Min;
            edge[i^1].flow -= Min;
            cost += edge[i].cost * (ll)Min;
        }
        flow += Min;
    }
    return flow;
}


int main()
{
	int cas;
	scanf("%d",&cas);
	for(int kase=1;kase<=cas;kase++)
	{
		int M;
		ll c;
		scanf("%d%lld",&M,&c);
		int start=0,end=2*M+1;
		init(end+1);
		for(int i=1;i<=M;i++)
		{
			int n,s,e;
			ll m,p;
		    scanf("%lld%d%lld%d%d",&m,&n,&p,&s,&e);
		    addedge(start,2*i-1,n,m);
		    addedge(2*i,end,s,-p);
		    for(int j=i;j<=min(i+e,M);j++)
		    addedge(2*i-1,2*j,0x3f3f3f3f,(ll)(j-i)*c);
		}
		ll cost;
		minCostMaxflow(start,end,cost);
		printf("Case %d: %lld\n",kase,-cost);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值