bzoj1834 [ZJOI2010]network 网络扩容

bzoj1834 [ZJOI2010]network 网络扩容

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

求:

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

(nleq10^3, mleq5 imes10^3, kleq10)

费用流


对于原图中的边 ((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;
}
原文地址:https://www.cnblogs.com/Juanzhang/p/10425580.html