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

#include <algorithm>
#include <iostream>
#include <vector>

#define INF 100000000

using namespace std;

int V, match[2001];
bool used[2001];
vector<int> G[2001];

void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
}

bool dfs(int v) {
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    int u = G[v][i], w = match[u];
    if (w < 0 || !used[w] && dfs(w)) {
      match[v] = u;
      match[u] = v;
      return true;
    }
  }
  return false;
}

int bipartite_matching() {
  int res = 0;
  fill(match, match + 2001, -1);
  for (int v = 0; v < V; v++) {
    if (match[v] < 0) {
      fill(used, used + 2001, false);
      if (dfs(v))
        res++;
    }
  }
  return res;
}
int main(void) {

  int n, m, l, u, v, d, dist[101][101], graph[1001][1001], p[1001], t[1001];

  while (cin >> n >> m >> l, n | m | l) {

    for (int i = 0; i < 2001; i++)
      G[i].clear();

    fill(dist[0], dist[101], INF);
    fill(graph[0], graph[1001], 0);

    for (int i = 0; i < 101; i++)
      dist[i][i] = 0;
    for (int i = 0; i < m; i++) {
      cin >> u >> v >> d;
      dist[u][v] = dist[v][u] = d;
    }

    for (int i = 0; i < l; i++) {
      cin >> p[i] >> t[i];
    }

    for (int k = 0; k < n; k++)
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

    for (int i = 0; i < l; i++)
      for (int j = 0; j < l; j++)
        if (i != j && dist[p[i]][p[j]] + t[i] <= t[j])
          graph[i][j] = 1;

    for (int i = 0; i < l; i++) {
      for (int j = 0; j < l; j++) {
        if (i != j && graph[i][j])
          add_edge(i, j + l);
      }
    }
    V = 2 * l;
    cout << l - bipartite_matching() << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>

#define INF 100000000

using namespace std;

int V, match[2001];
bool used[2001];
vector<int> G[2001];

void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
}

bool dfs(int v) {
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    int u = G[v][i], w = match[u];
    if (w < 0 || !used[w] && dfs(w)) {
      match[v] = u;
      match[u] = v;
      return true;
    }
  }
  return false;
}

int bipartite_matching() {
  int res = 0;
  fill(match, match + 2001, -1);
  for (int v = 0; v < V; v++) {
    if (match[v] < 0) {
      fill(used, used + 2001, false);
      if (dfs(v))
        res++;
    }
  }
  return res;
}

int main(void) {

  int n, m, l, u, v, d, dist[101][101], graph[1001][1001], p[1001], t[1001];

  while (cin >> n >> m >> l, n | m | l) {

    for (int i = 0; i < 2001; i++)
      G[i].clear();

    fill(dist[0], dist[101], INF);
    fill(graph[0], graph[1001], 0);

    for (int i = 0; i < 101; i++)
      dist[i][i] = 0;
    for (int i = 0; i < m; i++) {
      cin >> u >> v >> d;
      dist[u][v] = dist[v][u] = d;
    }

    for (int i = 0; i < l; i++) {
      cin >> p[i] >> t[i];
    }

    for (int k = 0; k < n; k++)
      for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
          dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

    for (int i = 0; i < l; i++)
      for (int j = 0; j < l; j++)
        if (i != j && dist[p[i]][p[j]] + t[i] <= t[j])
          graph[i][j] = 1;

    for (int k = 0; k < l; k++)
      for (int i = 0; i < l; i++)
        for (int j = 0; j < l; j++)
          graph[i][j] |= graph[i][k] & graph[k][j];

    for (int i = 0; i < l; i++) {
      for (int j = 0; j < l; j++) {
        if (i != j && graph[i][j])
          add_edge(i, j + l);
      }
    }
    V = 2 * l;
    cout << l - bipartite_matching() << endl;
  }
  return 0;
}