现在的位置: 首页 > 综合 > 正文

ZOJ 3904 Beer Problem 最大费用最大流

2017年11月23日 ⁄ 综合 ⁄ 共 4132字 ⁄ 字号 评论关闭

最大费用最大流,当费用为负时直接退出


Beer Problem


Time Limit: 2 Seconds      Memory Limit: 32768 KB


Everyone knows that World Finals of ACM ICPC 2004 were held in Prague. Besides its greatest architecture and culture, Prague is world famous for its beer. Though drinking too much is
probably not good for contestants, many teams took advantage of tasting greatest beer for really low prices.

A new beer producing company Drink Anywhere is planning to distribute its product in several of the n European cities. The brewery is located near Prague, that we would
certainly call city number 1. For delivering beer to other cities, the company is planning to use logistics company Drive Anywhere that provides m routes for carrying goods. Each route is described by the cities it connects (products can
be transported in either direction), its capacity --- the number of barrels of beer that can be transported along this route each day, and the cost of transporting one barrel of beer along it. To deliver beer to some city it may be necessary (or advantageous)
to use several routes consequently, and maybe even deliver beer using several different paths.

Each city is in turn characterized by the price that local pubs and restaurants are ready to pay for one barrel of beer. You may assume that demand for beer is essentially unlimited in
each city, since this is the product that will always find its consumer.

Drink Anywhere is not planning to distribute its beer in Prague for a while, because of the high competition there, so it is just planning to provide beer to other cities for
now. Help it to find out, what is the maximal income per day it can get.

Input

The first line of the input file contains n and m --- the number of cities in Europe we consider and the number of delivery routes respectively (2 ≤ n ≤ 100),
1 ≤ m ≤ 2000). The next line contains n - 1 integer numbers --- prices of a barrel of beer in European cities 2, 3 ..., n respectively (prices are positive integers and do not exceded 1000).

The following m lines contain four integer numbers each and describe delivery routes. Each route is specified by the numbers of cities it connects, its capacity, and the price
of transporting one barrel of beer along it (the capacity and the price are positive integers, they do not exceed 1000).

There are multiple cases. Process to the end of file.

Output

Output the maximal income the company can get each day.

Sample Input

4 4
80 50 130
1 2 80 50
2 4 40 90
3 1 40 60
3 4 30 50

Sample Output

3000

Hint

The company should deliver 80 barrels of beer to the second city (using the first route it costs 50 per barrel to deliver beer, income is 30 per barrel, 2400 total), and 30 barrels to
the fourth city (the best path uses routes 3 and 4, it costs 110 to deliver a barrel, income is 20 per barrel, 600 total). It is not profitable to deliver beer to the third city, so the company should not do it.


Author: Andrew Stankevich
Source: Andrew Stankevich's Contest #11

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int maxn=5000;
const int INF=0x3f3f3f3f;

struct Edge
{
    int to,next,cap,flow,cost;
}edge[maxn*2];

int Adj[maxn],Size,N;

void init()
{
    memset(Adj,-1,sizeof(Adj)); Size=0;
}

void addedge(int u,int v,int cap,int cost)
{
    edge[Size].to=v;
    edge[Size].next=Adj[u];
    edge[Size].cost=cost;
    edge[Size].cap=cap;
    edge[Size].flow=0;
    Adj[u]=Size++;
}

void Add_Edge(int u,int v,int cap,int cost)
{
    addedge(u,v,cap,cost);
    addedge(v,u,0,-cost);
}

int dist[maxn],vis[maxn],pre[maxn];

bool spfa(int s,int t)
{
    queue<int> q;
    for(int i=0;i<N;i++)
    {
        dist[i]=-INF;vis[i]=false;pre[i]=-1;
    }
    dist[s]=0,vis[s]=true; q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        for(int i=Adj[u];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].cap>edge[i].flow&&
                    dist[v]<dist[u]+edge[i].cost)
            {
                dist[v]=dist[u]+edge[i].cost;
                pre[v]=i;
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
    }
    if(pre[t]==-1) return false;
    return true;
}

int MinCostMaxFlow(int s,int t,int &cost)
{
    int flow=0;
    cost=0;
    while(spfa(s,t))
    {
        int Min=INF;
        for(int i=pre[t];~i;i=pre[edge[i^1].to])
        {
            if(Min>edge[i].cap-edge[i].flow)
                Min=edge[i].cap-edge[i].flow;
        }
        if(dist[t]<0) break;
        for(int i=pre[t];~i;i=pre[edge[i^1].to])
        {
            edge[i].flow+=Min;
            edge[i^1].flow-=Min;
            cost+=edge[i].cost*Min;
        }
        flow+=Min;
    }
    return flow;
}

int pi[maxn],bian[maxn];

int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        ///Sink : 0 Sank : n+1
        for(int i=2;i<=n;i++)
        {
            scanf("%d",pi+i);
        }
        for(int i=0;i<m;i++)
        {
            int u,v,capa,price;
            scanf("%d%d%d%d",&u,&v,&capa,&price);
            Add_Edge(u,v,capa,-price);
            Add_Edge(v,u,capa,-price);
        }
        Add_Edge(0,1,INF,0);
        for(int i=2;i<=n;i++)
        {
            bian[i]=Size;
            Add_Edge(i,n+1,INF,pi[i]);
        }
        N=n+2;
        int flow,cost;
        flow=MinCostMaxFlow(0,n+1,cost);
        cout<<cost<<endl;
    }
    return 0;
}

抱歉!评论已关闭.