Problem p01368 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define LINF (1LL << 60)
#define INF (1 << 30)
#define MAX_N 2160
typedef long long Int;
struct E {
  int to, rev;
  Int lim;
  E(int x, Int y, int z) {
    to = x;
    lim = y;
    rev = z;
  }
};

vector<E> edge[MAX_N];
int lev[MAX_N];
int iter[MAX_N];

void make_edge(int a, int b, Int l) {
  edge[a].push_back(E(b, l, edge[b].size()));
  edge[b].push_back(E(a, 0, edge[a].size() - 1));
}

Int dfs(int s, int g, Int f) {
  if (s == g)
    return f;
  for (int &i = iter[s]; i < edge[s].size(); i++) {
    E &e = edge[s][i];
    if (lev[e.to] <= lev[s] || e.lim <= 0)
      continue;
    Int tmp = dfs(e.to, g, min(f, e.lim));
    if (!tmp)
      continue;
    e.lim -= tmp;
    edge[e.to][e.rev].lim += tmp;
    return tmp;
  }
  return 0;
}

void bfs(int x) {
  queue<int> q;
  q.push(x);
  int p = 0;
  while (!q.empty()) {
    for (int i = q.size(); i--;) {
      int tmp = q.front();
      q.pop();
      if (lev[tmp] != INF)
        continue;
      lev[tmp] = p;
      for (int j = 0; j < edge[tmp].size(); j++) {
        if (edge[tmp][j].lim > 0 && lev[edge[tmp][j].to] == INF)
          q.push(edge[tmp][j].to);
      }
    }
    p++;
  }
}

Int max_flow(int s, int g) {
  Int res = 0;
  bool fin = false;
  while (!fin) {
    fill(lev, lev + MAX_N, INF);
    fill(iter, iter + MAX_N, 0);
    bfs(s);
    fin = true;
    while (true) {
      int p = dfs(s, g, INF);
      if (p == 0)
        break;
      fin = false;
      res += p;
    }
  }
  return res;
}

int dist[108][108];
int p[108], t[108];
int main() {
  int n, m, l, u, v, d;
  while (cin >> n >> m >> l, n | m | l) {
    for (int i = 0; i < 2160; i++)
      edge[i].clear();
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (i == j)
          dist[i][j] = 0;
        else
          dist[i][j] = INF - 1;
      }
    }
    for (int i = 0; i < m; i++) {
      cin >> u >> v >> d;
      dist[u][v] = d;
      dist[v][u] = d;
    }
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        for (int k = 0; k < n; k++)
          dist[j][k] = min(dist[j][i] + dist[i][k], dist[j][k]);
    for (int i = 0; i < l; i++) {
      cin >> p[i] >> t[i];
    }
    for (int i = 0; i < l; i++) {
      make_edge(l * 2, i, 1);
      make_edge(i + l, l * 2 + 1, 1);
      for (int j = 0; j < l; j++) {
        if (i == j)
          continue;
        if (t[i] + dist[p[i]][p[j]] <= t[j]) {
          make_edge(i, j + l, 1);
        }
      }
    }
    cout << l - max_flow(l * 2, l * 2 + 1) << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define LINF (1LL << 60)
#define INF (1 << 30)
#define MAX_N 2160
typedef long long Int;
struct E {
  int to, rev;
  Int lim;
  E(int x, Int y, int z) {
    to = x;
    lim = y;
    rev = z;
  }
};

vector<E> edge[MAX_N];
int lev[MAX_N];
int iter[MAX_N];

void make_edge(int a, int b, Int l) {
  edge[a].push_back(E(b, l, edge[b].size()));
  edge[b].push_back(E(a, 0, edge[a].size() - 1));
}

Int dfs(int s, int g, Int f) {
  if (s == g)
    return f;
  for (int &i = iter[s]; i < edge[s].size(); i++) {
    E &e = edge[s][i];
    if (lev[e.to] <= lev[s] || e.lim <= 0)
      continue;
    Int tmp = dfs(e.to, g, min(f, e.lim));
    if (!tmp)
      continue;
    e.lim -= tmp;
    edge[e.to][e.rev].lim += tmp;
    return tmp;
  }
  return 0;
}

void bfs(int x) {
  queue<int> q;
  q.push(x);
  int p = 0;
  while (!q.empty()) {
    for (int i = q.size(); i--;) {
      int tmp = q.front();
      q.pop();
      if (lev[tmp] != INF)
        continue;
      lev[tmp] = p;
      for (int j = 0; j < edge[tmp].size(); j++) {
        if (edge[tmp][j].lim > 0 && lev[edge[tmp][j].to] == INF)
          q.push(edge[tmp][j].to);
      }
    }
    p++;
  }
}

Int max_flow(int s, int g) {
  Int res = 0;
  bool fin = false;
  while (!fin) {
    fill(lev, lev + MAX_N, INF);
    fill(iter, iter + MAX_N, 0);
    bfs(s);
    fin = true;
    while (true) {
      int p = dfs(s, g, INF);
      if (p == 0)
        break;
      fin = false;
      res += p;
    }
  }
  return res;
}

int dist[108][108];
int p[1080], t[1080];
int main() {
  int n, m, l, u, v, d;
  while (cin >> n >> m >> l, n | m | l) {
    for (int i = 0; i < 2160; i++)
      edge[i].clear();
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (i == j)
          dist[i][j] = 0;
        else
          dist[i][j] = INF - 1;
      }
    }
    for (int i = 0; i < m; i++) {
      cin >> u >> v >> d;
      dist[u][v] = d;
      dist[v][u] = d;
    }
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        for (int k = 0; k < n; k++)
          dist[j][k] = min(dist[j][i] + dist[i][k], dist[j][k]);
    for (int i = 0; i < l; i++) {
      cin >> p[i] >> t[i];
    }
    for (int i = 0; i < l; i++) {
      make_edge(l * 2, i, 1);
      make_edge(i + l, l * 2 + 1, 1);
      for (int j = 0; j < l; j++) {
        if (i == j)
          continue;
        if (t[i] + dist[p[i]][p[j]] <= t[j]) {
          make_edge(i, j + l, 1);
        }
      }
    }
    cout << l - max_flow(l * 2, l * 2 + 1) << endl;
  }
  return 0;
}