【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
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
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\n", ans ); 158 return 0; 159 }