Problem p00673 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>

using namespace std;

#define dump(n) cerr << "# " << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;

struct Train {
  int leave, arrive, fare;
  Train() {}
  Train(int l, int a, int f) : leave(l), arrive(a), fare(f) {}
};

struct Vertex {
  int kind; // 0:leave, 1:arrive
  int index, time;
  Vertex() {}
  Vertex(int k, int i, int t) : kind(k), index(i), time(t) {}
  bool operator<(const Vertex &v) const {
    if (kind != v.kind)
      return kind < v.kind;
    if (index != v.index)
      return index < v.index;
    if (time != v.time)
      return time < v.time;
    return false;
  }
};

struct Edge {
  int src, dst, cap, cost;
  Edge() {}
  Edge(int s, int d, int ca, int co) : src(s), dst(d), cap(ca), cost(co) {}
};
typedef vector<vector<Edge>> Graph;

int MinCostFlow(const Graph &_g, int begin, int end, int flow) {
  int size = _g.size();
  Graph g(size);
  vvi rev(size);
  rep(i, size) foreach (e, _g[i]) {
    g[i].push_back(*e);
    g[e->dst].push_back(Edge(e->dst, e->src, 0, -e->cost));
    rev[i].push_back(g[e->dst].size() - 1);
    rev[e->dst].push_back(g[i].size() - 1);
  }

  int res = 0;
  vi pots(size);
  while (flow) {
    vi dist(size, INFTY);
    vector<pii> prev(size, mp(-1, -1));
    priority_queue<pii, vector<pii>, greater<pii>> pq;
    pq.push(mp(0, begin));
    dist[begin] = 0;
    while (!pq.empty()) {
      int curd = pq.top().first, curv = pq.top().second;
      pq.pop();
      if (dist[curv] < curd)
        continue;
      rep(i, g[curv].size()) {
        Edge e = g[curv][i];
        if (e.cap == 0)
          continue;
        int newdist = dist[e.src] + e.cost + pots[e.src] - pots[e.dst];
        if (dist[e.dst] > newdist) {
          dist[e.dst] = newdist;
          prev[e.dst] = mp(e.src, i);
          pq.push(mp(newdist, e.dst));
        }
      }
    }

    if (prev[end].first == -1)
      return -1;
    rep(i, size) pots[i] += dist[i];

    int f = flow;
    for (int v = end; v != begin; v = prev[v].first) {
      Edge e = g[prev[v].first][prev[v].second];
      f = min(f, e.cap);
    }
    for (int v = end; v != begin; v = prev[v].first) {
      int i = prev[v].first, j = prev[v].second;
      g[i][j].cap -= f;
      g[g[i][j].dst][rev[i][j]].cap += f;
    }
    flow -= f;
    res += f * pots[end];
  }

  return res;
}

int main() {
  for (int n; cin >> n, n;) {
    vector<vector<Train>> train(n - 1);
    rep(i, n - 1) {
      int m;
      cin >> m;
      train[i].resize(m);
      rep(j, m) cin >> train[i][j].leave >> train[i][j].arrive >>
          train[i][j].fare;
    }
    int c;
    cin >> c;

    map<Vertex, int> vmap;
    rep(i, n - 1){rep(j, train[i].size()){vmap[Vertex(0, i, train[i][j].leave)];
    vmap[Vertex(1, i, train[i][j].arrive)];
  }
}
{
  int id = 0;
  foreach (i, vmap)
    i->second = id++;
}

int lcnt = 0, acnt = 0;
foreach (i, vmap) {
  if (i->first.kind == 0)
    lcnt++;
  if (i->first.kind == 1)
    acnt++;
}

Graph g(lcnt + acnt + acnt + 2);
int source = lcnt + acnt + acnt, sink = source + 1;

rep(i, n - 1) {
  rep(j, train[i].size()) {
    int src = vmap[Vertex(0, i, train[i][j].leave)];
    int dst = vmap[Vertex(1, i, train[i][j].arrive)];
    g[src].push_back(Edge(src, dst, 1, train[i][j].fare));
  }
}
rep(i, n - 1) {
  rep(j, train[i].size()) {
    int src = vmap[Vertex(1, i, train[i][j].arrive)];
    int dst = src + acnt;
    if (g[src].size() == 0)
      g[src].push_back(Edge(src, dst, 1, 0));
  }
}
rep(i, n - 1) {
  if (i == n - 2)
    continue;
  rep(j, train[i].size()) {
    rep(k, train[i + 1].size()) {
      if (train[i][j].arrive <= train[i + 1][k].leave) {
        int src = vmap[Vertex(1, i, train[i][j].arrive)] + acnt;
        int dst = vmap[Vertex(0, i + 1, train[i + 1][k].leave)];
        g[src].push_back(Edge(src, dst, 1, 0));
      }
    }
  }
}
rep(i, train[0].size()) {
  int dst = vmap[Vertex(0, 0, train[0][i].leave)];
  g[source].push_back(Edge(source, dst, 1, 0));
}
rep(i, train[n - 2].size()) {
  int src = vmap[Vertex(1, n - 2, train[n - 2][i].arrive)] + acnt;
  g[src].push_back(Edge(src, sink, INFTY, 0));
}

int lo = 0, hi = c + 1;
while (lo + 1 < hi) {
  int mi = (lo + hi) / 2;
  if (MinCostFlow(g, source, sink, mi) == -1)
    hi = mi;
  else
    lo = mi;
}

int flow = lo;
int cost = MinCostFlow(g, source, sink, flow);
printf("%d %d\\n", flow, cost);
}

return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <utility>

using namespace std;

#define dump(n) cerr << "# " << #n << "=" << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;

struct Train {
  int leave, arrive, fare;
  Train() {}
  Train(int l, int a, int f) : leave(l), arrive(a), fare(f) {}
};

struct Vertex {
  int kind; // 0:leave, 1:arrive
  int index, time;
  Vertex() {}
  Vertex(int k, int i, int t) : kind(k), index(i), time(t) {}
  bool operator<(const Vertex &v) const {
    if (kind != v.kind)
      return kind < v.kind;
    if (index != v.index)
      return index < v.index;
    if (time != v.time)
      return time < v.time;
    return false;
  }
};

struct Edge {
  int src, dst, cap, cost;
  Edge() {}
  Edge(int s, int d, int ca, int co) : src(s), dst(d), cap(ca), cost(co) {}
};
typedef vector<vector<Edge>> Graph;

void BFS(const Graph &g, int begin, const vvi &capacity, const vvi &flow,
         vi &label) {
  queue<pii> q;
  q.push(mp(begin, 0));
  while (!q.empty()) {
    pii v = q.front();
    q.pop();
    if (label[v.first] <= v.second)
      continue;
    label[v.first] = v.second;
    foreach (e, g[v.first])
      if (capacity[e->src][e->dst] - flow[e->src][e->dst] > 0)
        q.push(mp(e->dst, v.second + 1));
  }
}

int DFS(const Graph &g, int v, int end, const vvi &capacity, vvi &flow,
        vi &label, vi &finished, int f) {
  if (v == end)
    return f;
  if (finished[v])
    return 0;
  finished[v] = true;

  foreach (e, g[v]) {
    if (label[e->src] >= label[e->dst])
      continue;
    int r = capacity[e->src][e->dst] - flow[e->src][e->dst];
    if (r <= 0)
      continue;
    int inc = DFS(g, e->dst, end, capacity, flow, label, finished, min(f, r));
    if (inc > 0) {
      flow[e->src][e->dst] += inc;
      flow[e->dst][e->src] -= inc;
      finished[v] = false;
      return inc;
    }
  }

  return 0;
}

int Dinic(const Graph &_g, int begin, int end) {
  int size = _g.size();

  // tûüÌÓðÁ¦é(eÊÍ0É·é)
  Graph g = _g;
  rep(i, size) foreach (e, _g[i]) g[e->dst].push_back(
      Edge(e->dst, e->src, 0, -1));

  vvi capacity(size, vi(size)), flow(size, vi(size));
  rep(i, size) foreach (e, g[i]) capacity[e->src][e->dst] += e->cap;

  for (;;) {
    vi label(size, INFTY);
    BFS(g, begin, capacity, flow, label);
    if (label[end] == INFTY)
      break;
    vi finished(size);
    while (DFS(g, begin, end, capacity, flow, label, finished, INFTY))
      ;
  }

  return accumulate(all(flow[begin]), 0);
}

int MinCostFlow(const Graph &_g, int begin, int end, int flow) {
  int size = _g.size();
  Graph g(size);
  vvi rev(size);
  rep(i, size) foreach (e, _g[i]) {
    g[i].push_back(*e);
    g[e->dst].push_back(Edge(e->dst, e->src, 0, -e->cost));
    rev[i].push_back(g[e->dst].size() - 1);
    rev[e->dst].push_back(g[i].size() - 1);
  }

  int res = 0;
  vi pots(size);
  while (flow) {
    vi dist(size, INFTY);
    vector<pii> prev(size, mp(-1, -1));
    priority_queue<pii, vector<pii>, greater<pii>> pq;
    pq.push(mp(0, begin));
    dist[begin] = 0;
    while (!pq.empty()) {
      int curd = pq.top().first, curv = pq.top().second;
      pq.pop();
      if (dist[curv] < curd)
        continue;
      rep(i, g[curv].size()) {
        Edge e = g[curv][i];
        if (e.cap == 0)
          continue;
        int newdist = dist[e.src] + e.cost + pots[e.src] - pots[e.dst];
        if (dist[e.dst] > newdist) {
          dist[e.dst] = newdist;
          prev[e.dst] = mp(e.src, i);
          pq.push(mp(newdist, e.dst));
        }
      }
    }

    if (prev[end].first == -1)
      return -1;
    rep(i, size) pots[i] += dist[i];

    int f = flow;
    for (int v = end; v != begin; v = prev[v].first) {
      Edge e = g[prev[v].first][prev[v].second];
      f = min(f, e.cap);
    }
    for (int v = end; v != begin; v = prev[v].first) {
      int i = prev[v].first, j = prev[v].second;
      g[i][j].cap -= f;
      g[g[i][j].dst][rev[i][j]].cap += f;
    }
    flow -= f;
    res += f * pots[end];
  }

  return res;
}

int main() {
  for (int n; cin >> n, n;) {
    vector<vector<Train>> train(n - 1);
    rep(i, n - 1) {
      int m;
      cin >> m;
      train[i].resize(m);
      rep(j, m) cin >> train[i][j].leave >> train[i][j].arrive >>
          train[i][j].fare;
    }
    int c;
    cin >> c;

    map<Vertex, int> vmap;
    rep(i, n - 1){rep(j, train[i].size()){vmap[Vertex(0, i, train[i][j].leave)];
    vmap[Vertex(1, i, train[i][j].arrive)];
  }
}
{
  int id = 0;
  foreach (i, vmap)
    i->second = id++;
}

int lcnt = 0, acnt = 0;
foreach (i, vmap) {
  if (i->first.kind == 0)
    lcnt++;
  if (i->first.kind == 1)
    acnt++;
}

Graph g(lcnt + acnt + acnt + 2);
int source = lcnt + acnt + acnt, sink = source + 1;

rep(i, n - 1) {
  rep(j, train[i].size()) {
    int src = vmap[Vertex(0, i, train[i][j].leave)];
    int dst = vmap[Vertex(1, i, train[i][j].arrive)];
    g[src].push_back(Edge(src, dst, 1, train[i][j].fare));
  }
}
rep(i, n - 1) {
  rep(j, train[i].size()) {
    int src = vmap[Vertex(1, i, train[i][j].arrive)];
    int dst = src + acnt;
    if (g[src].size() == 0)
      g[src].push_back(Edge(src, dst, 1, 0));
  }
}
rep(i, n - 1) {
  if (i == n - 2)
    continue;
  rep(j, train[i].size()) {
    rep(k, train[i + 1].size()) {
      if (train[i][j].arrive <= train[i + 1][k].leave) {
        int src = vmap[Vertex(1, i, train[i][j].arrive)] + acnt;
        int dst = vmap[Vertex(0, i + 1, train[i + 1][k].leave)];
        g[src].push_back(Edge(src, dst, 1, 0));
      }
    }
  }
}
rep(i, train[0].size()) {
  int dst = vmap[Vertex(0, 0, train[0][i].leave)];
  g[source].push_back(Edge(source, dst, 1, 0));
}
rep(i, train[n - 2].size()) {
  int src = vmap[Vertex(1, n - 2, train[n - 2][i].arrive)] + acnt;
  g[src].push_back(Edge(src, sink, INFTY, 0));
}

int flow = min(Dinic(g, source, sink), c);
int cost = MinCostFlow(g, source, sink, flow);
printf("%d %d\\n", flow, cost);
}

return 0;
}