ZOJ 3362 Beer Problem

Beer Problem

Time Limit: 2000ms
Memory Limit: 32768KB
This problem will be judged on ZJU. Original ID: 3362
64-bit integer IO format: %lld      Java class name: Main
 

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.

 

Source

Author

Andrew Stankevich
 
解题:一切皆网络流!学了一句很叼的口号。。。。。。是不是很叼?
 
啤酒,运输到各地,要赚钱,那么肯定是每单元的运费少于每单元的啤酒售价。至于什么生成费之类的,暂不考虑。如何建边?直接把各个城市的售价取负数,然后源点1号城市到其他城市的费用取整数。一旦要亏,必然出现从源点到汇点的距离,也就是费用>=0.如果这样,不必继续下去了,没赚。卖一瓶啤酒赚的钱还不够车费,搞毛线啊
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 200;
18 struct arc{
19     int v,w,f,next;
20     arc(int x = 0,int y = 0,int z = 0,int nxt = 0){
21         v = x;
22         w = y;
23         f = z;
24         next = nxt;
25     }
26 };
27 arc e[10000];
28 int head[maxn],p[maxn],d[maxn];
29 bool in[maxn];
30 int n,m,S,T,tot;
31 queue<int>q;
32 void add(int u,int v,int w,int f){
33     e[tot] = arc(v,w,f,head[u]);
34     head[u] = tot++;
35     e[tot] = arc(u,-w,0,head[v]);
36     head[v] = tot++;
37 }
38 bool spfa(){
39     for(int i = 1; i <= T; i++){
40         d[i] = INF;
41         in[i] = false;
42         p[i] = -1;
43     }
44     while(!q.empty()) q.pop();
45     d[S] = 0;
46     in[S] = true;
47     q.push(S);
48     while(!q.empty()){
49         int u = q.front();
50         q.pop();
51         in[u] = false;
52         for(int i = head[u]; ~i; i = e[i].next){
53             if(e[i].f > 0 && d[e[i].v] > d[u] + e[i].w){
54                 d[e[i].v] = d[u] + e[i].w;
55                 p[e[i].v] = i;
56                 if(!in[e[i].v]){
57                     in[e[i].v] = true;
58                     q.push(e[i].v);
59                 }
60             }
61         }
62     }
63     return d[T] < 0;
64 }
65 int solve(){
66     int tmp = 0,minV;
67     while(spfa()){
68         minV = INF;
69         for(int i = p[T]; ~i; i = p[e[i^1].v])
70             minV = min(minV,e[i].f);
71         for(int i = p[T]; ~i; i = p[e[i^1].v]){
72             e[i].f -= minV;
73             e[i^1].f += minV;
74         }
75         tmp += minV*d[T];
76     }
77     return tmp;
78 }
79 int main() {
80     int tmp,u,v,f;
81     while(~scanf("%d %d",&n,&m)){
82         S = 1;
83         T = n+1;
84         memset(head,-1,sizeof(head));
85         tot = 0;
86         for(int i = 2; i <= n; i++){
87             scanf("%d",&tmp);
88             add(i,T,-tmp,INF);
89         }
90         for(int i = 0; i < m; i++){
91             scanf("%d %d %d %d",&u,&v,&f,&tmp);
92             add(u,v,tmp,f);
93             add(v,u,tmp,f);
94         }
95         printf("%d
",-solve());
96     }
97     return 0;
98 }
View Code
原文地址:https://www.cnblogs.com/crackpotisback/p/3975649.html