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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

#define INF (1 << 28)
#define SOUR (L + L)
#define SINK (L + L + 1)

bool flow[2005][2005];
bool DAG[1005][1005];
int L, v[2020];

class Node {
public:
  vector<int> to;
};

void Connect(vector<Node> &node, int src, int dst) {
  flow[dst][src] = 1;
  node[src].to.push_back(dst);
  node[dst].to.push_back(src);
}

int dfs(int p, int T, int mf, vector<Node> &graph, vector<int> &level,
        vector<bool> &finished) {
  if (p == T)
    return mf;
  if (finished[p])
    return 0;

  finished[p] = true;

  for (int i = 0; i < graph[p].to.size(); i++) {
    int next = graph[p].to[i], fw = (flow[p][next] ? 0 : 1);

    // if(p==SOUR) fw=1;
    if (level[p] >= level[next])
      continue;
    if (fw <= 0)
      continue;

    int f = dfs(next, T, min(mf, fw), graph, level, finished);
    if (f > 0) {
      finished[p] = false;
      flow[p][next] = 1;
      flow[next][p] = 0;
      return f;
    }
  }

  return 0;
}

int dinic(int S, int T, vector<Node> &graph) {
  bool end = false;
  int total = 0;
  while (!end) {
    end = true;
    vector<int> level(graph.size(), -1);
    level[S] = 0;

    queue<int> q;
    q.push(S);
    while (!q.empty()) {
      int n = q.front();
      q.pop();
      for (int i = 0; i < graph[n].to.size(); i++) {
        int next = graph[n].to[i];
        if (level[next] != -1)
          continue;
        if (flow[n][next])
          continue;
        level[next] = level[n] + 1;
        q.push(next);
      }
    }

    if (level[T] == -1)
      break;

    vector<bool> finished(graph.size());
    while (1) {
      int fw = dfs(S, T, INF, graph, level, finished);
      if (fw <= 0)
        break;

      total += fw;
      end = false;
    }
  }

  return total;
}

int main() {
  int N, M;
  while (scanf("%d%d%d", &N, &M, &L), (N || M || L)) {
    int d[105][105];
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) {
        d[i][j] = INF;
        d[i][i] = d[j][j] = 0;
      }

    for (int i = 0; i < M; i++) {
      int u, v, c;
      scanf("%d%d%d", &u, &v, &c);
      d[u][v] = c;
      d[v][u] = c;
    }

    for (int k = 0; k < N; k++)
      for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
          d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        }

    int s[1005], t[1005];
    for (int i = 0; i < L; i++) {
      scanf("%d%d", &s[i], &t[i]);
    }

    memset(flow, 0, sizeof(flow));
    memset(DAG, 0, sizeof(DAG));

    vector<Node> node(SINK + 1);

    bool beg[1005] = {0}, end[1005] = {0};
    for (int i = 0; i < L; i++) {
      Connect(node, SOUR, i);
      Connect(node, L + i, SINK);

      for (int j = 0; j < L; j++) {
        if (i == j)
          continue;
        if (d[s[i]][s[j]] + t[i] <= t[j]) {
          Connect(node, i, L + j);
        }
      }
    }

    printf("%d\\n", L - dinic(SOUR, SINK, node));
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

#define INF (1 << 28)
#define SOUR (L + L)
#define SINK (L + L + 1)

int flow[2005][2005], capa[2005][2005], L, v[2020];
bool DAG[1005][1005];

class Node {
public:
  vector<int> to;
};

void Connect(vector<Node> &node, int u, int v, int w) {
  flow[v][u] += w;
  capa[u][v] += w;
  capa[v][u] += w;
  node[u].to.push_back(v);
  node[v].to.push_back(u);
}

int dfs(int p, int T, int mf, vector<Node> &graph, vector<int> &level,
        vector<bool> &finished) {
  if (p == T)
    return mf;
  if (finished[p])
    return 0;

  finished[p] = true;

  for (int i = 0; i < graph[p].to.size(); i++) {
    int next = graph[p].to[i], fw = capa[p][next] - flow[p][next];
    if (level[p] >= level[next])
      continue;
    if (fw <= 0)
      continue;

    int f = dfs(next, T, min(mf, fw), graph, level, finished);
    if (f > 0) {
      finished[p] = false;
      flow[p][next] += f;
      flow[next][p] -= f;

      return f;
    }
  }

  return 0;
}

int dinic(int S, int T, vector<Node> &graph) {
  bool end = false;
  int total = 0;
  while (!end) {
    end = true;
    vector<int> level(graph.size(), -1);
    level[S] = 0;

    queue<int> q;
    q.push(S);
    while (!q.empty()) {
      int n = q.front();
      q.pop();
      for (int i = 0; i < graph[n].to.size(); i++) {
        int next = graph[n].to[i];
        if (level[next] != -1)
          continue;
        if (capa[n][next] - flow[n][next] <= 0)
          continue;
        level[next] = level[n] + 1;
        q.push(next);
      }
    }

    if (level[T] == -1)
      break;

    vector<bool> finished(graph.size());
    while (1) {
      int fw = dfs(S, T, INF, graph, level, finished);
      if (fw <= 0)
        break;

      total += fw;
      end = false;
    }
  }

  return total;
}

void Connect(int u, int v, int w, vector<Node> &graph) {
  graph[u].to.push_back(v);
  graph[v].to.push_back(u);
  capa[u][v] += w;
  capa[v][u] += w;

  flow[v][u] += w;
}

int main() {
  int N, M;
  while (scanf("%d%d%d", &N, &M, &L), (N || M || L)) {
    int d[105][105];
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++)
        d[i][j] = INF;

    for (int i = 0; i < M; i++) {
      int u, v, c;
      scanf("%d%d%d", &u, &v, &c);
      d[u][v] = c;
      d[v][u] = c;
    }

    for (int k = 0; k < N; k++)
      for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++) {
          d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        }

    int s[1005], t[1005];
    for (int i = 0; i < L; i++) {
      scanf("%d%d", &s[i], &t[i]);
    }

    memset(flow, 0, sizeof(flow));
    memset(capa, 0, sizeof(capa));
    memset(DAG, 0, sizeof(DAG));

    vector<Node> node(SINK + 1);

    bool beg[1005] = {0}, end[1005] = {0};
    for (int i = 0; i < L; i++)
      for (int j = 0; j < L; j++) {
        if (i == j)
          continue;
        if (d[s[i]][s[j]] + t[i] <= t[j]) {
          DAG[i][j] = 1;
          beg[j] = 1;
          end[i] = 1;
        }
      }
    for (int i = 0; i < L; i++) {
      if (!beg[i]) {
        Connect(node, SOUR, i, INF);
      }
      if (!end[i]) {
        Connect(node, L + i, SINK, INF);
      }
    }

    int add = 0;
    for (int i = 0; i < L; i++) {
      if (!beg[i] && !end[i]) {
        ++add;
      }
      for (int j = 0; j < L; j++) {
        if (DAG[i][j]) {
          Connect(node, i, L + j, 1);
        }
      }
    }

    printf("%d\\n", dinic(SOUR, SINK, node) + add);
  }
}