zoukankan      html  css  js  c++  java
  • [CODEVS1916] 负载平衡问题(最小费用最大流)

    传送门

    输入所有 a[i],求出平均值 sum,每个 a[i] -= sum

    那么如果 a[i] > 0,从 s 向 i 连一条容量为 a[i] 费用为 0 的有向边

      如果 a[i] < 0,从 i 向 t 连一条容量为 -a[i] 费用为 0 的有向边

    每个点 i 和它相邻的两个点连一条容量为 INF 费用为 1 的有向边

    求出最小费用最大流即为答案

    ——代码

      1 #include <queue>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #define INF 1e9
      6 #define N 1000001
      7 #define min(x, y) ((x) < (y) ? (x) : (y))
      8 
      9 int n, cnt, s, t;
     10 int a[101], dis[N], pre[N];
     11 int head[N], to[N << 1], val[N << 1], cost[N << 1], next[N << 1];
     12 bool vis[N];
     13 
     14 inline int read()
     15 {
     16     int x = 0, f = 1;
     17     char ch = getchar();
     18     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
     19     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
     20     return x * f;
     21 }
     22 
     23 inline void add(int x, int y, int z, int c)
     24 {
     25     to[cnt] = y;
     26     val[cnt] = z;
     27     cost[cnt] = c;
     28     next[cnt] = head[x];
     29     head[x] = cnt++;
     30 }
     31 
     32 inline bool spfa()
     33 {
     34     int i, u, v;
     35     std::queue <int> q;
     36     memset(vis, 0, sizeof(vis));
     37     memset(pre, -1, sizeof(pre));
     38     memset(dis, 127 / 3, sizeof(dis));
     39     q.push(s);
     40     dis[s] = 0;
     41     while(!q.empty())
     42     {
     43         u = q.front(), q.pop();
     44         vis[u] = 0;
     45         for(i = head[u]; i ^ -1; i = next[i])
     46         {
     47             v = to[i];
     48             if(val[i] && dis[v] > dis[u] + cost[i])
     49             {
     50                 dis[v] = dis[u] + cost[i];
     51                 pre[v] = i;
     52                 if(!vis[v])
     53                 {
     54                     q.push(v);
     55                     vis[v] = 1;
     56                 }
     57             }
     58         }
     59     }
     60     return pre[t] ^ -1;
     61 }
     62 
     63 inline int dinic()
     64 {
     65     int i, d, sum = 0;
     66     while(spfa())
     67     {
     68         d = INF;
     69         for(i = pre[t]; i ^ -1; i = pre[to[i ^ 1]]) d = min(d, val[i]);
     70         for(i = pre[t]; i ^ -1; i = pre[to[i ^ 1]])
     71         {
     72             val[i] -= d;
     73             val[i ^ 1] += d;
     74         }
     75         sum += dis[t] * d;
     76     }
     77     return sum;
     78 }
     79 
     80 int main()
     81 {
     82     int i, j, x, sum = 0;
     83     n = read();
     84     s = 0, t = n + 1;
     85     memset(head, -1, sizeof(head));
     86     for(i = 1; i <= n; i++)
     87     {
     88         a[i] = read();
     89         sum += a[i];
     90     }
     91     sum /= n;
     92     for(i = 1; i <= n; i++) a[i] -= sum;
     93     for(i = 1; i <= n; i++)
     94     {
     95         if(a[i] > 0) add(s, i, a[i], 0), add(i, s, 0, 0);
     96         if(a[i] < 0) add(i, t, -a[i], 0), add(t, i, 0, 0);
     97         if(i == 1)
     98         {
     99             add(i, 2, INF, 1), add(2, i, 0, -1);
    100             add(i, n, INF, 1), add(n, i, 0, -1);
    101         }
    102         else if(i == n)
    103         {
    104             add(i, n - 1, INF, 1), add(n - 1, i, 0, -1);
    105             add(i, 1, INF, 1), add(1, i, 0, -1);
    106         }
    107         else
    108         {
    109             add(i, i + 1, INF, 1), add(i + 1, i, 0, -1);
    110             add(i, i - 1, INF, 1), add(i - 1, i, 0, -1);
    111         }
    112     }
    113     printf("%d
    ", dinic());
    114     return 0;
    115 }
    View Code
  • 相关阅读:
    asp.net2.0中App_GlobalResources的使用
    KPI(Key Performance Indicators )
    Dictionary集合
    SQL连接查询1 内联接查询
    如何在Web.config中注册用户控件和自定义控件
    JavaScript中【数据类型】和【数组类型】的区别
    递归求斐波拉数列函数
    SQL连接查询2 外连接(左右联接查询)
    启示
    “帽子戏法”从何而来?
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7008687.html
Copyright © 2011-2022 走看看