首页 > 代码库 > BZOJ1834 [ZJOI2010]network 网络扩容

BZOJ1834 [ZJOI2010]network 网络扩容

网络流训练好题。。。但是要给差评!蒟蒻表示这就是板子题,然后做了半个小时T T

先跑一边最大流,得到第一问答案ans。

第二问:原先的边不动,费用为0。

然后对每条边在上面再加一条边,流量为inf,费用为修改费用。

n向T连一条边,流量为ans + k,费用为0。

跑一边费用流即可。

 

  1 /**************************************************************  2     Problem: 1834  3     User: rausen  4     Language: C++  5     Result: Accepted  6     Time:64 ms  7     Memory:1296 kb  8 ****************************************************************/  9   10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13   14 using namespace std; 15 const int N = 1005; 16 const int M = 10005; 17 const int inf = (int) 1e9; 18   19 struct Edges { 20     int x, y, c, w; 21 } E[M]; 22   23 struct edges { 24     int next, to, f, cost; 25     edges() {} 26     edges(int _n, int _t, int _f, int _c) : next(_n), to(_t), f(_f), cost(_c) {} 27 } e[M << 1]; 28   29 int n, m, k, last_ans; 30 int S, T; 31 int first[N], tot; 32 int q[N], d[N], g[N]; 33 bool v[N]; 34   35 inline int read() { 36     int x = 0, sgn = 1; 37     char ch = getchar(); 38     while (ch < 0 || 9 < ch) { 39         if (ch == -) sgn = -1; 40         ch = getchar(); 41     } 42     while (0 <= ch && ch <= 9) { 43         x = x * 10 + ch - 0; 44         ch = getchar(); 45     } 46     return sgn * x; 47 } 48   49 inline void Add_Edges(int x, int y, int f, int c) { 50     e[++tot] = edges(first[x], y, f, c), first[x] = tot; 51     e[++tot] = edges(first[y], x, 0, -c), first[y] = tot; 52 } 53   54 bool bfs() { 55     memset(d, 0, sizeof(d)); 56     q[1] = S, d[S] = 1; 57     int l, r, x, y; 58     for (l = r = 1; l != (r + 1) % N; (++l) %= N) 59         for (x = first[q[l]]; x; x = e[x].next){ 60             y = e[x].to; 61             if (!d[y] && e[x].f) 62                 q[(++r) %= N] = y, d[y] = d[q[l]] + 1; 63         } 64   65     return d[T]; 66 } 67     68 int dinic(int p, int limit) { 69     if (p == T || !limit) return limit; 70     int x, y, tmp, rest = limit; 71     for (x = first[p]; x; x = e[x].next) 72         if (d[y = e[x].to] == d[p] + 1 && e[x].f && rest) {  73             tmp = dinic(y, min(rest, e[x].f)); 74             rest -= tmp; 75             e[x].f -= tmp, e[x ^ 1].f += tmp; 76             if (!rest) return limit; 77         } 78     if (limit == rest) d[p] = 0; 79     return limit - rest; 80 } 81     82 int Dinic() { 83     int res = 0, x; 84     while (bfs()) 85         res += dinic(S, inf); 86     return res; 87 } 88   89 void work1() { 90     int i; 91     memset(first, 0, sizeof(first)); 92     for (i = tot = 1; i <= m; ++i) 93         Add_Edges(E[i].x, E[i].y, E[i].c, 0); 94     S = 1, T = n; 95     printf("%d ", last_ans = Dinic()); 96 } 97   98 inline int calc() { 99     int flow = inf, x;100     for (x = g[T]; x; x = g[e[x ^ 1].to])101         flow = min(flow, e[x].f);102     for (x = g[T]; x; x = g[e[x ^ 1].to])103         e[x].f -= flow, e[x ^ 1].f += flow;104     return flow;105 }106   107 bool spfa() {108     int x, y, l, r;109     for (x = 1; x <= T; ++x)110         d[x] = inf;111     d[S] = 0, v[S] = 1, q[0] = S;112     for(l = r = 0; l != (r + 1) % N; ++l %= N) {113         for (x = first[q[l]]; x; x = e[x].next)114             if (d[q[l]] + e[x].cost < d[y = e[x].to] && e[x].f) {115                 d[y] = d[q[l]] + e[x].cost;116                 g[y] = x;117                 if (!v[y])118                     q[(++r) %= N] = y, v[y] = 1;119             }120         v[q[l]] = 0;121     }122     return d[T] != inf;123 }124  125 inline int work() {126     int res = 0;127     while (spfa())128         res += calc() * d[T];129     return res;130 }131  132 void work2() {133     int i;134     memset(first, 0, sizeof(first));135     for (i = tot = 1; i <= m; ++i) {136         Add_Edges(E[i].x, E[i].y, E[i].c, 0);137         Add_Edges(E[i].x, E[i].y, inf, E[i].w);138     }139     Add_Edges(n, n + 1, last_ans + k, 0);140     S = 1, T = n + 1;141     printf("%d\n", work());142 }143  144 int main() {145     int i;146     n = read(), m = read(), k = read();147     for (i = 1; i <= m; ++i)148         E[i].x = read(), E[i].y = read(), E[i].c = read(), E[i].w = read();149     work1();150     work2();151     return 0;152 }
View Code

 

BZOJ1834 [ZJOI2010]network 网络扩容