bzoj1834 [ZJOI2010]network 网络扩容

bzoj1834 [ZJOI2010]network 网络扩容

给定一张有向图,每条边都有一个容量 \(C\) 和一个扩容费用 \(W\) ,即将容量扩大 \(1\) 所需的费用。

求:

  1. \(1\)\(N\) 的最大流;
  2. \(1\)\(N\) 的最大流增加 \(K\) 所需的最小扩容费用。

\(n\leq10^3,\ m\leq5\times10^3,\ k\leq10\)

费用流


对于原图中的边 \((u,\ v,\ w,\ c)\) ,连边 \((u,\ v,\ w,\ 0),\ (u,\ v,\ \inf,\ c)\)

限制 \(K\) 的流量可以连边 \((T,\ T',\ K,\ 0)\)\((S',\ S,\ K,\ 0)\)

时间复杂度 \(O(\) 能过 \()\)

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1010, maxm = 1e4 + 10, inf = 1 << 30;
int N, M, K;

namespace maxflow {
static int S, T, q[maxn], h[maxn], f[maxn], pre[maxn];
static struct edges {
  int nxt, to, w;
  edges(int x = 0, int y = 0, int z = 0) :
    nxt(x), to(y), w(z) {}
} e[maxm];

void addline(int u, int v, int w) {
  static int cnt = 1;
  e[++cnt] = edges(h[u], v, w), h[u] = cnt;
  e[++cnt] = edges(h[v], u, 0), h[v] = cnt;
}

bool bfs() {
  memset(f, 0, sizeof f);
  int l = 1, r = 1;
  q[1] = S, f[S] = inf;
  while (l <= r) {
    int u = q[l++];
    for (int i = h[u]; i; i = e[i].nxt) {
      int v = e[i].to;
      if (e[i].w && !f[v]) {
        pre[v] = i, q[++r] = v;
        f[v] = min(f[u], e[i].w);
        if (v == T) return 1;
      }
    }
  }
  return 0;
}

int EK() {
  int res = 0;
  while (bfs()) {
    for (int u = T; u != S; u = e[pre[u] ^ 1].to) {
      e[pre[u]].w -= f[T], e[pre[u] ^ 1].w += f[T];
    }
    res += f[T];
  }
  return res;
}
}

namespace mcmf {
static bool vis[maxn];
static int S, T, h[maxn], f[maxn], dis[maxn], pre[maxn];
static struct edges {
  int nxt, to, w, c;
  edges(int _n = 0, int _t = 0, int _w = 0, int _c = 0) :
    nxt(_n), to(_t), w(_w), c(_c) {}
} e[maxm << 1];
static queue <int> q;

void addline(int u, int v, int w, int c) {
  static int cnt = 1;
  e[++cnt] = edges(h[u], v, w, c), h[u] = cnt;
  e[++cnt] = edges(h[v], u, 0, -c), h[v] = cnt;
}

bool spfa() {
  memset(dis, 0x3f, sizeof dis);
  q.push(S), dis[S] = 0, f[S] = inf;
  while (!q.empty()) {
    int u = q.front();
    q.pop(), vis[u] = 0;
    for (int i = h[u]; i; i = e[i].nxt) {
      int v = e[i].to;
      if (e[i].w && dis[v] > dis[u] + e[i].c) {
        pre[v] = i;
        dis[v] = dis[u] + e[i].c;
        f[v] = min(f[u], e[i].w);
        if (!vis[v]) vis[v] = 1, q.push(v);
      }
    }
  }
  return dis[T] < 1e9;
}

int EK() {
  int res = 0;
  while (spfa()) {
    for (int u = T; u != S; u = e[pre[u] ^ 1].to) {
      e[pre[u]].w -= f[T], e[pre[u] ^ 1].w += f[T];
    }
    res += f[T] * dis[T];
  }
  return res;
}
}

int main() {
  scanf("%d %d %d", &N, &M, &K);
  for (int i = 1; i <= M; i++) {
    int u, v, w, c;
    scanf("%d %d %d %d", &u, &v, &w, &c);
    maxflow::addline(u, v, w);
    mcmf::addline(u, v, w, 0);
    mcmf::addline(u, v, inf, c);
  }
  maxflow::S = 1;
  maxflow::T = N;
  int tmp = maxflow::EK();
  mcmf::S = 1;
  mcmf::T = N + 1;
  mcmf::addline(N, N + 1, tmp + K, 0);
  printf("%d %d", tmp, mcmf::EK());
  return 0;
}
posted @ 2019-02-24 11:09  cnJuanzhang  阅读(159)  评论(0编辑  收藏  举报