zoukankan      html  css  js  c++  java
  • zoj 3231(上下界费用流)

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

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

    代码如下:

      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
    ", ans);
    149     }
    150     return 0;
    151 }
    View Code
  • 相关阅读:
    Qwt的安装与使用
    深入浅出分析Linux设备驱动程序中断
    QT连接数据库的基本操作
    linux下摄像头抓图源码
    QTE 触控屏支持
    linux网络多线程编程实例
    wubi (windows下硬盘安装Linux)
    快速体验Linux的3种方式
    在Visual Studio 2005中安装Qt 4.3.2
    Enterprise Architect 字体
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3725258.html
Copyright © 2011-2022 走看看