zoj3231 Apple Transportation(最大流)

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

Apple Transportation

Time Limit: 1 Second      Memory Limit: 32768 KB

There's a big apple tree in the forest. In the tree there are N nodes (numbered from 0 to N - 1), and the nodes are connected by branches. On each node of the tree, there is a squirrel. In the autumn, some apples will grow on the nodes. After all apples are ripe, each squirrel will collect all the apples of their own node and store them. For the demand to be harmonic, they decide to redistribute the apples to minimize the variance (please refer to the hint) of apples in all nodes. Obviously, an apple cannot be divided into several parts. To reach this goal, some transportation should be taken. The cost of transporting x apples from node u to node v is x * distance (node u, node v). Now given the current amount of apples of each node and the structure of the apple tree, you should help the squirrels to find the minimal cost to redistribute the apples.

Input

Input consists of multiple test cases (less than 80 cases)!

For each test case, the first line contains an integer N (1 <= N <= 100), which is the number of the nodes in the tree.

The following line contains N integers a0,a1,...,aN-1 (0 <= ai <= 10000), representing the amount of the i-th node's apples.

The following N - 1 lines each contain three integers uvc (0 <= u,v <= N - 1, 0 <= c <= 1000), which means node u and node v are connected by a branch, the length of the branch is c.

There is a blank line between consecutive cases.

Output

For each case output the minimal total transportation cost. The minimal cost is guaranteed to be less than 231.

Sample Input

3
1 2 3
0 1 1
0 2 1

3
1 3 3
0 1 3
0 2 4

2
1 2
0 1 1

Sample Output

1
3
0

Hint

The formula to calculate the variance  of x1x2, ..., xn:


Author: ZHOU, Yilun
Source: ZOJ Monthly, August 2009

 

上下界费用流的水题。。。懒的写题解了。。。sad

  1 //#####################
  2 //Author:fraud
  3 //Blog: http://www.cnblogs.com/fraud/
  4 //#####################
  5 #include <iostream>
  6 #include <sstream>
  7 #include <ios>
  8 #include <iomanip>
  9 #include <functional>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <string>
 13 #include <list>
 14 #include <queue>
 15 #include <deque>
 16 #include <stack>
 17 #include <set>
 18 #include <map>
 19 #include <cstdio>
 20 #include <cstdlib>
 21 #include <cmath>
 22 #include <cstring>
 23 #include <climits>
 24 #include <cctype>
 25 using namespace std;
 26 #define XINF INT_MAX
 27 #define INF 0x3FFFFFFF
 28 #define MP(X,Y) make_pair(X,Y)
 29 #define PB(X) push_back(X)
 30 #define REP(X,N) for(int X=0;X<N;X++)
 31 #define REP2(X,L,R) for(int X=L;X<=R;X++)
 32 #define DEP(X,R,L) for(int X=R;X>=L;X--)
 33 #define CLR(A,X) memset(A,X,sizeof(A))
 34 #define IT iterator
 35 typedef long long ll;
 36 typedef pair<int,int> PII;
 37 typedef vector<PII> VII;
 38 typedef vector<int> VI;
 39 struct edge
 40 {
 41     int to,cap,cost,rev;
 42     edge(int _to,int _cap,int _cost,int _rev)
 43     {
 44         to=_to;cap=_cap;cost=_cost;rev=_rev;
 45     }
 46 };
 47 int V;
 48 const int MAX_V=410; 
 49 vector<edge> G[MAX_V];
 50 int dis[MAX_V];
 51 int prevv[MAX_V],preve[MAX_V];//最短路中的前驱结点和对应的边 
 52 void add_edge(int from,int to,int cap,int cost)
 53 {
 54     G[from].push_back(edge(to,cap,cost,G[to].size()));
 55     G[to].push_back(edge(from,0,-cost,G[from].size()-1));
 56 }
 57 int vis[MAX_V];
 58 int min_cost_flow(int s,int t,int f)//如果不能在增广则返回-1 
 59 {
 60     int res=0;
 61     while(f>0)
 62     {
 63         fill(dis,dis+V,INF);
 64         dis[s]=0;
 65         queue<int>q;
 66         CLR(vis,0);
 67         q.push(s);
 68         while(!q.empty())
 69         {
 70             int v=q.front();
 71             q.pop();
 72             vis[v]=0;
 73             for(int i=0;i<G[v].size();i++)
 74             {
 75                 edge &e=G[v][i];
 76                 if(e.cap>0&&dis[e.to]>dis[v]+e.cost)
 77                 {
 78                     dis[e.to]=dis[v]+e.cost;
 79                     prevv[e.to]=v;
 80                     preve[e.to]=i;
 81                     if(!vis[e.to])
 82                     {
 83                         q.push(e.to);
 84                         vis[e.to]=1;
 85                     }
 86                 }
 87             }
 88         }
 89     /*    bool update=1;
 90         while(update)
 91         {
 92             update=false;
 93             for(int v=0;v<V;v++)
 94             {
 95                 if(dis[v]==INF) continue;
 96                 for(int i=0;i<G[v].size();i++)
 97                 {
 98                     edge &e=G[v][i];
 99                     if(e.cap>0&&dis[e.to]>dis[v]+e.cost)
100                     {
101                         dis[e.to]=dis[v]+e.cost;
102                         prevv[e.to]=v;
103                         preve[e.to]=i;
104                         update=1;
105                     }
106                 }
107             }
108         }*/
109         if(dis[t]==INF)
110         {
111             return -1;
112         }
113         int d=f;
114         for(int v=t;v!=s;v=prevv[v])
115         {
116             d=min(d,G[prevv[v]][preve[v]].cap);
117         }
118         f-=d;
119         res+=d*dis[t];
120         for(int v=t;v!=s;v=prevv[v])
121         {
122             edge &e=G[prevv[v]][preve[v]];
123             e.cap-=d;
124             G[v][e.rev].cap+=d;
125         }
126         //cout<<f<<endl;
127     //    cout<<"ok"<<endl;
128     }
129     return res;
130 }
131 int a[MAX_V];
132 int main()
133 {
134     int n;
135     while(scanf("%d",&n)!=EOF){
136         int sum=0;
137         for(int i=1;i<=n;i++){
138             scanf("%d",a+i);
139             sum+=a[i];
140         }
141         CLR(prevv,-1);
142         CLR(preve,-1);
143         for(int i=0;i<n+3;i++)G[i].clear();
144         int s=0,tt=n+1,t=n+2;
145         int temp=sum/n;
146         V=t+1;
147         for(int i=1;i<=n;i++){
148             add_edge(s,i,a[i],0);
149             add_edge(i,tt,1,0);
150             add_edge(i,t,temp,0);
151         }
152         add_edge(tt,t,sum-n*temp,0);
153         int u,v,d;
154         
155         for(int i=0;i<n-1;i++){
156             scanf("%d%d%d",&u,&v,&d);
157             u++;
158             v++;
159             add_edge(u,v,INF,d);
160             add_edge(v,u,INF,d);    
161         }
162         printf("%d
",min_cost_flow(s,t,sum));
163         
164         
165     }
166     return 0;
167 }
代码君
原文地址:https://www.cnblogs.com/fraud/p/4354779.html