BZOJ1834 [ZJOI2010]network 网络扩容
2014-12-14 17:16
274 查看
网络流训练好题。。。但是要给差评!蒟蒻表示这就是板子题,然后做了半个小时T T
先跑一边最大流,得到第一问答案ans。
第二问:原先的边不动,费用为0。
然后对每条边在上面再加一条边,流量为inf,费用为修改费用。
n向T连一条边,流量为ans + k,费用为0。
跑一边费用流即可。
View Code
先跑一边最大流,得到第一问答案ans。
第二问:原先的边不动,费用为0。
然后对每条边在上面再加一条边,流量为inf,费用为修改费用。
n向T连一条边,流量为ans + k,费用为0。
跑一边费用流即可。
/************************************************************** Problem: 1834 User: rausen Language: C++ Result: Accepted Time:64 ms Memory:1296 kb ****************************************************************/ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1005; const int M = 10005; const int inf = (int) 1e9; struct Edges { int x, y, c, w; } E[M]; struct edges { int next, to, f, cost; edges() {} edges(int _n, int _t, int _f, int _c) : next(_n), to(_t), f(_f), cost(_c) {} } e[M << 1]; int n, m, k, last_ans; int S, T; int first , tot; int q , d , g ; bool v ; inline int read() { int x = 0, sgn = 1; char ch = getchar(); while (ch < '0' || '9' < ch) { if (ch == '-') sgn = -1; ch = getchar(); } while ('0' <= ch && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return sgn * x; } inline void Add_Edges(int x, int y, int f, int c) { e[++tot] = edges(first[x], y, f, c), first[x] = tot; e[++tot] = edges(first[y], x, 0, -c), first[y] = tot; } bool bfs() { memset(d, 0, sizeof(d)); q[1] = S, d[S] = 1; int l, r, x, y; for (l = r = 1; l != (r + 1) % N; (++l) %= N) for (x = first[q[l]]; x; x = e[x].next){ y = e[x].to; if (!d[y] && e[x].f) q[(++r) %= N] = y, d[y] = d[q[l]] + 1; } return d[T]; } int dinic(int p, int limit) { if (p == T || !limit) return limit; int x, y, tmp, rest = limit; for (x = first[p]; x; x = e[x].next) if (d[y = e[x].to] == d[p] + 1 && e[x].f && rest) { tmp = dinic(y, min(rest, e[x].f)); rest -= tmp; e[x].f -= tmp, e[x ^ 1].f += tmp; if (!rest) return limit; } if (limit == rest) d[p] = 0; return limit - rest; } int Dinic() { int res = 0, x; while (bfs()) res += dinic(S, inf); return res; } void work1() { int i; memset(first, 0, sizeof(first)); for (i = tot = 1; i <= m; ++i) Add_Edges(E[i].x, E[i].y, E[i].c, 0); S = 1, T = n; printf("%d ", last_ans = Dinic()); } inline int calc() { int flow = inf, x; for (x = g[T]; x; x = g[e[x ^ 1].to]) flow = min(flow, e[x].f); for (x = g[T]; x; x = g[e[x ^ 1].to]) e[x].f -= flow, e[x ^ 1].f += flow; return flow; } bool spfa() { int x, y, l, r; for (x = 1; x <= T; ++x) d[x] = inf; d[S] = 0, v[S] = 1, q[0] = S; for(l = r = 0; l != (r + 1) % N; ++l %= N) { for (x = first[q[l]]; x; x = e[x].next) if (d[q[l]] + e[x].cost < d[y = e[x].to] && e[x].f) { d[y] = d[q[l]] + e[x].cost; g[y] = x; if (!v[y]) q[(++r) %= N] = y, v[y] = 1; } v[q[l]] = 0; } return d[T] != inf; } inline int work() { int res = 0; while (spfa()) res += calc() * d[T]; return res; } void work2() { int i; memset(first, 0, sizeof(first)); for (i = tot = 1; i <= m; ++i) { Add_Edges(E[i].x, E[i].y, E[i].c, 0); Add_Edges(E[i].x, E[i].y, inf, E[i].w); } Add_Edges(n, n + 1, last_ans + k, 0); S = 1, T = n + 1; printf("%d\n", work()); } int main() { int i; n = read(), m = read(), k = read(); for (i = 1; i <= m; ++i) E[i].x = read(), E[i].y = read(), E[i].c = read(), E[i].w = read(); work1(); work2(); return 0; }
View Code
相关文章推荐
- 【BZOJ1834】[ZJOI2010]network 网络扩容【最大流】【最小费用最大流】【残量网络】
- BZOJ 1834 [ZJOI2010]network 网络扩容
- bzoj1834[ZJOI2010]network 网络扩容【最大流+费用流】
- 【最大流/费用流】BZOJ1834-[ZJOI2010]network 网络扩容
- BZOJ1834 [ZJOI2010] network 网络扩容
- 【BZOJ】【1834】【ZJOI2010】Network 网络扩容
- 【bzoj1834】[ZJOI2010]network 网络扩容 费用流
- bzoj 1834 [ZJOI2010] network 网络扩容 题解
- 【bzoj1834】[ZJOI2010]network 网络扩容(wikioi1362)
- 【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)
- bzoj 1834: [ZJOI2010]network 网络扩容 网络流+费用流
- [BZOJ1834][ZJOI2010]network 网络扩容
- 【BZOJ 1834】 [ZJOI2010]network 网络扩容
- bzoj 1834: [ZJOI2010]network 网络扩容(isap+费用流)
- 【BZOJ 1834】 [ZJOI2010]network 网络扩容
- BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)
- [BZOJ 1834] [ZJOI2010]network 网络扩容
- bzoj1834 [ZJOI2010]network 网络扩容
- bzoj 1834 [ZJOI2010]network 网络扩容(MCMF)
- bzoj 1834: [ZJOI2010]network 网络扩容