码迷,mamicode.com
首页 > 其他好文 > 详细

zoj 3231(上下界费用流)

时间:2014-05-16 21:50:35      阅读:491      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   class   code   c   

题意:树上每个节点上有若干苹果,边上带权,问你最小费用使得书上的苹果方差最小。

思路:上下费用流问题,参考http://blog.csdn.net/qq564690377/article/details/8870587

代码如下:

bubuko.com,布布扣
  1 /**************************************************
  2  * Author     : xiaohao Z
  3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
  4  * Last modified : 2014-05-13 12:02
  5  * Filename     : zoj_3231_2.cpp
  6  * Description     : 
  7  * ************************************************/
  8 
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <cmath>
 14 #include <algorithm>
 15 #include <queue>
 16 #include <stack>
 17 #include <vector>
 18 #include <set>
 19 #include <map>
 20 #define MP(a, b) make_pair(a, b)
 21 #define PB(a) push_back(a)
 22 
 23 using namespace std;
 24 typedef long long ll;
 25 typedef pair<int, int> pii;
 26 typedef pair<unsigned int,unsigned int> puu;
 27 typedef pair<int, double> pid;
 28 typedef pair<ll, int> pli;
 29 typedef pair<int, ll> pil;
 30 
 31 const int INF = 0x3f3f3f3f;
 32 const double eps = 1E-6;
 33 const int MAXN = 10000;
 34 const int MAXM = 100000;
 35 struct Edge{int to,next,cap,flow,cost;}edge[MAXM];
 36 int head[MAXN],tol;
 37 int pre[MAXN],dis[MAXN];
 38 bool vis[MAXN];
 39 int N;//节点总个数,节点编号从0~N-1
 40 
 41 void init(int n)
 42 {
 43     N = n;
 44     tol = 0;
 45     memset(head,-1,sizeof(head));
 46 }
 47 
 48 void addedge(int u,int v,int cap,int cost)
 49 {
 50     edge[tol].to = v;
 51     edge[tol].cap = cap;
 52     edge[tol].cost = cost;
 53     edge[tol].flow = 0;
 54     edge[tol].next = head[u];
 55     head[u] = tol++;
 56     edge[tol].to = u;
 57     edge[tol].cap = 0;
 58     edge[tol].cost = -cost;
 59     edge[tol].flow = 0;
 60     edge[tol].next = head[v];
 61     head[v] = tol++;
 62 }
 63 bool spfa(int s,int t)
 64 {
 65     queue<int>q;
 66     for(int i = 0; i < N; i++)
 67     {
 68         dis[i] = INF;
 69         vis[i] = false;
 70         pre[i] = -1;
 71     }
 72     dis[s] = 0;
 73     vis[s] = true;
 74     q.push(s);
 75     while(!q.empty())
 76     {
 77         int u = q.front();
 78         q.pop();
 79         vis[u] = false;
 80         for(int i = head[u]; i != -1; i = edge[i].next)
 81         {
 82             int v = edge[i].to;
 83             if(edge[i].cap > edge[i].flow &&
 84                     dis[v] > dis[u] + edge[i].cost )
 85             {
 86                 dis[v] = dis[u] + edge[i].cost;
 87                 pre[v] = i;
 88                 if(!vis[v])
 89                 {
 90                     vis[v] = true;
 91                     q.push(v);
 92                 }
 93             }
 94         }
 95     }
 96     if(pre[t] == -1)return false;
 97     else return true;
 98 }
 99 //返回的是最大流,cost存的是最小费用
100 int minCostMaxflow(int s,int t,int &cost)
101 {
102     int flow = 0;
103     cost = 0;
104     while(spfa(s,t))
105     {
106         int Min = INF;
107         for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
108         {
109             if(Min > edge[i].cap - edge[i].flow)
110                 Min = edge[i].cap - edge[i].flow;
111         }
112         for(int i = pre[t]; i != -1; i = pre[edge[i^1].to])
113         {
114             edge[i].flow += Min;
115             edge[i^1].flow -= Min;
116             cost += edge[i].cost * Min;
117         }
118         flow += Min;
119     }
120     return flow;
121 }
122 
123 int main()
124 {
125 //    freopen("in.txt", "r", stdin);
126     int a, b, n, vex[101], val, sum;
127     while(scanf("%d", &n)!=EOF){
128         sum = 0;
129         for(int i=1; i<=n; i++){
130             scanf("%d", &vex[i]);
131             sum += vex[i];
132         }
133         init(n+3);
134         for(int i=1; i<n; i++){
135             scanf("%d%d%d", &a, &b, &val);
136             a++, b++;
137             addedge(a, b, INF, val);
138             addedge(b, a, INF, val);
139         }
140         for(int i=1; i<=n; i++){
141             addedge(0, i, vex[i], 0);
142             addedge(i, n+1, sum/n, 0);
143             addedge(i, n+2, 1, 0);
144         }
145         addedge(n+2, n+1, sum%n, 0);
146         int ans;
147         minCostMaxflow(0, n+1, ans);
148         printf("%d\n", ans);
149     }
150     return 0;
151 }
View Code

 

zoj 3231(上下界费用流),布布扣,bubuko.com

zoj 3231(上下界费用流)

标签:des   style   blog   class   code   c   

原文地址:http://www.cnblogs.com/shu-xiaohao/p/3725258.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!