【模板】最小费用最大流

一个费用流板子:

namespace GR {
  const int N = 405;
  const int M = 15005;
  const int INF = (int)1e9;
  int s, t, n, yun, flow, cost;
  int las[N], cur[N], dis[N], iq[N], vi[N];
  int to[M << 1], pr[M << 1], ca[M << 1], co[M << 1];
  void Init(int _s, int _t, int _n) {
    s = _s, t = _t, n = _n, yun = 1;
    fill(las, las + 1 + n, 0);
  }
  void Add(int a, int b, int c, int d) {
    to[++yun] = b, ca[yun] = c, co[yun] = d, pr[yun] = las[a], las[a] = yun;
    to[++yun] = a, ca[yun] = 0, co[yun] = -d, pr[yun] = las[b], las[b] = yun;
  }
  int Spfa() {
    static queue<int> Q;
    fill(dis, dis + 1 + n, INF);
    fill(iq, iq + 1 + n, 0);
    dis[s] = 0, Q.push(s), iq[s] = 1;
    for (int x; !Q.empty(); ) {
      x = Q.front(), iq[x] = 0, Q.pop();
      for (int i = las[x]; i; i = pr[i]) {
        if (ca[i] > 0 && dis[to[i]] > dis[x] + co[i]) {
          dis[to[i]] = dis[x] + co[i];
          if (!iq[to[i]]) iq[to[i]] = 1, Q.push(to[i]);
        }
      }
    }
    return dis[t] != INF;
  }
  int Dfs(int x, int fl) {
    if (x == t || fl == 0) return fl;
    int us = 0;
    vi[x] = 1;
    for (int i = cur[x]; i; i = pr[i]) {
      cur[x] = i;
      if (ca[i] > 0 && !vi[to[i]] && dis[to[i]] == dis[x] + co[i]) {
        int f = Dfs(to[i], min(fl - us, ca[i]));
        ca[i] -= f, ca[i ^ 1] += f, us += f, cost += co[i] * f;
        if (fl == us) break;
      }
    }
    return us;
  }
  int Flow() {
    flow = cost = 0;
    while (Spfa()) {
      memcpy(cur, las, sizeof(int) * (n + 2));
      fill(vi, vi + 1 + n, 0);
      flow += Dfs(s, INF);
    }
    return flow;
  }
}
View Code

 

posted @ 2017-10-26 17:50  Dance_Of_Faith  阅读(187)  评论(0编辑  收藏  举报