zoukankan      html  css  js  c++  java
  • 【BZOJ1834】 [ZJOI2010]network 网络扩容

    Description

    给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。

    Input

    输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。

    Output

    输出文件一行包含两个整数,分别表示问题1和问题2的答案。

    Sample Input

    5 8 2
    1 2 5 8
    2 5 9 9
    5 1 6 2
    5 1 1 8
    1 2 8 7
    2 5 4 9
    1 2 1 1
    1 4 2 1

    Sample Output

    13 19
    30%的数据中,N<=100
    100%的数据中,N<=1000,M<=5000,K<=10

    Solution

    第一问可以直接用最大流跑。

    第二问新建源然后向旧源连一条容量为K, 费用0的边。其他就是原来的连容量c,费用0,新加的连容量inf,费用W。最后跑费用流即可。

    Code

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <queue>
      6 
      7 #ifdef WIN32
      8     #define LL "%I64d"
      9 #else
     10     #define LL "%lld"
     11 #endif
     12 
     13 #ifdef CT
     14     #define debug(...) printf(__VA_ARGS__)
     15     #define setfile() 
     16 #else
     17     #define debug(...)
     18     #define filename ""
     19     #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout)
     20 #endif
     21 
     22 #define R register
     23 #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
     24 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
     25 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
     26 #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
     27 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
     28 #define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x))
     29 char B[1 << 15], *S = B, *T = B;
     30 inline int F()
     31 {
     32     R char ch; R int cnt = 0; R bool minus = 0;
     33     while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
     34     ch == '-' ? minus = 1 : cnt = ch - '0';
     35     while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
     36     return minus ? -cnt : cnt;
     37 }
     38 #define maxn 1010
     39 #define maxm 100010
     40 struct edge
     41 {
     42     int a, b, w, c;
     43 }ee[maxm];
     44 struct Edge
     45 {
     46     Edge *next, *rev;
     47     int from, to, cap, cost;
     48 }*last[maxn], e[maxm], *ecnt = e, *cur[maxn], *prev[maxn];
     49 inline void link(R int a, R int b, R int w, R int c)
     50 {
     51     *++ecnt = (Edge) {last[a], ecnt + 1, a, b, w, c}; last[a] = ecnt;
     52     *++ecnt = (Edge) {last[b], ecnt - 1, b, a, 0, -c}; last[b] = ecnt;
     53 }
     54 #define inf 0x7fffffff
     55 int s, t, dep[maxn], ans, d[maxn];
     56 std::queue<int> q;
     57 inline bool bfs()
     58 {
     59     memset(dep, -1, sizeof (dep));
     60     dep[t] = 0; q.push(t);
     61     while (!q.empty())
     62     {
     63         R int now = q.front(); q.pop();
     64         for (R Edge *iter = last[now]; iter; iter = iter -> next)
     65         {
     66             R int pre = iter -> to;
     67             if (iter -> rev -> cap && dep[pre] == -1)
     68             {
     69                 dep[pre] = dep[now] + 1;
     70                 q.push(pre);
     71             }
     72         }
     73     }
     74     return dep[s] != -1;
     75 }
     76 int dfs(R int x, R int f)
     77 {
     78     if (x == t) return f;
     79     R int used = 0;
     80     for (R Edge* &iter = cur[x]; iter; iter = iter -> next)
     81     {
     82         R int pre = iter -> to;
     83         if (iter -> cap && dep[x] == dep[pre] + 1)
     84         {
     85             R int v = dfs(pre, dmin(iter -> cap, f - used));
     86             iter -> cap -= v;
     87             iter -> rev -> cap += v;
     88             used += v;
     89             if (f == used) return f;
     90         }
     91     }
     92     if (!used) dep[x] = -1;
     93     return used;
     94 }
     95 inline void dinic()
     96 {
     97     while (bfs())
     98     {
     99         memcpy(cur, last, sizeof last);
    100         ans += dfs(s, inf);
    101     }
    102 }
    103 bool inq[maxn];
    104 inline bool spfa()
    105 {
    106     for (R int i = 1; i <= t; ++i) d[i] = inf;
    107     q.push(s);
    108     while (!q.empty())
    109     {
    110         R int now = q.front(); q.pop(); inq[now] = 0;
    111         for (R Edge *iter = last[now]; iter; iter = iter -> next)
    112         {
    113             R int pre = iter -> to;
    114             if (iter -> cap && d[pre] > d[now] + iter -> cost)
    115             {
    116                 d[pre] = d[now] + iter -> cost;
    117                 prev[pre] = iter;
    118                 if (!inq[pre])
    119                 {
    120                     q.push(pre);
    121                     inq[pre] = 1;
    122                 }
    123             }
    124         }
    125     }
    126     return d[t] != inf;
    127 }
    128 inline void mcmf()
    129 {
    130     R int x = inf;
    131     for (R Edge *iter = prev[t]; iter; iter = prev[iter -> from])
    132         cmin(x, iter -> cap);
    133     for (R Edge *iter = prev[t]; iter; iter = prev[iter -> from])
    134     {
    135         iter -> cap -= x;
    136         iter -> rev -> cap += x;
    137         ans += x * iter -> cost;
    138     }
    139 }
    140 int main()
    141 {
    142 //    setfile();
    143     R int n = F(), m = F(), k = F();
    144     for (R int i = 1; i <= m; ++i)
    145     {
    146         R int a = F(), b = F(), w = F(), c = F();
    147         link(a, b, w, 0); ee[i] = (edge) {a, b, w, c};
    148     }
    149     s = 1; t = n;
    150     dinic();
    151     printf("%d ", ans );
    152     ans = 0;
    153     for (R int i = 1; i <= m; ++i) link(ee[i].a, ee[i].b, inf, ee[i].c);
    154     s = 0; t = n;
    155     link(s, 1, k, 0);
    156     while (spfa()) mcmf();
    157     printf("%d
    ", ans );
    158     return 0;
    159 }
  • 相关阅读:
    linux下gdb常用的调试命令 .
    Programming lessons I learned
    lvalue和rvalue、传值和传引用、木桶
    gnuplot的简明教程——英文版,很不错
    100 的阶乘末尾有多少个0?
    lvalue和rvalue、传值和传引用、木桶
    gnuplot的简明教程——英文版,很不错
    100 的阶乘末尾有多少个0?
    poj1728
    poj1809
  • 原文地址:https://www.cnblogs.com/cocottt/p/6619012.html
Copyright © 2011-2022 走看看