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

#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

// #define int long long
#define rep(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(c) begin(c), end(c)
const int INF =
    sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

struct BipartiteMatching {
  int n;
  vector<vector<int>> g;
  vector<int> match;
  vector<int> used;
  BipartiteMatching(int n) : n(n), g(n), match(n), used(n) {}
  void addEdge(int u, int v) {
    g[u].emplace_back(v);
    g[v].emplace_back(u);
  }
  int maximumMatching() {
    int cnt = 0;
    fill(match.begin(), match.end(), -1);
    for (int v = 0; v < n; v++) {
      if (match[v] == -1) {
        fill(used.begin(), used.end(), false);
        if (augment(v))
          cnt++;
      }
    }
    return cnt;
  }
  bool augment(int v) {
    used[v] = true;
    for (int u : g[v]) {
      int w = match[u];
      if (w == -1 || (!used[w] && augment(w))) {
        match[v] = u;
        match[u] = v;
        return true;
      }
    }
    return false;
  }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  for (int N, M, L; cin >> N >> M >> L && N;) {
    vector<vector<int>> g(N, vector<int>(N, INF));
    rep(i, 0, M) {
      int u, v, d;
      cin >> u >> v >> d;
      g[u][v] = g[v][u] = d;
    }
    rep(i, 0, N) g[i][i] = 0;
    rep(k, 0, N) rep(i, 0, N) rep(j, 0, N) {
      if (g[i][k] != INF && g[k][j] != INF)
        g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
    }

    vector<int> p(L), t(L);
    rep(i, 0, L) { cin >> p[i] >> t[i]; }
    BipartiteMatching bm(L + L);
    int source = L + L, sink = source + 1;
    rep(i, 0, L) {
      rep(j, 0, L) {
        if (i == j)
          continue;
        if (g[p[i]][p[j]] <= t[j] - t[i]) {
          bm.addEdge(i, L + j);
        }
      }
    }
    auto ans = L - bm.maximumMatching();
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

// #define int long long
#define rep(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(c) begin(c), end(c)
const int INF =
    sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

struct MinimumCostMaximumFlow {
  using Index = int;
  using Flow = int;
  using Cost = int;
  static const Flow kInfCapacity = INF;
  static const Cost kInfCost = INF;
  struct Edge {
    Index s, d;
    Flow capacity;
    Cost cost;
  };
  using Edges = vector<Edge>;
  using Graph = vector<Edges>;
  Graph g;
  void init(Index n) { g.assign(n, Edges()); }
  void addArc(Index i, Index j, Flow capacity = kInfCapacity,
              Cost cost = Cost()) {
    Edge e, f;
    e.d = j, f.d = i;
    e.capacity = capacity, f.capacity = 0;
    e.cost = cost, f.cost = -cost;
    g[i].push_back(e);
    g[j].push_back(f);
    g[i].back().s = (Index)g[j].size() - 1;
    g[j].back().s = (Index)g[i].size() - 1;
  }
  void addEdge(Index i, Index j, Flow capacity = kInfCapacity,
               Cost cost = Cost()) {
    addArc(i, j, capacity, cost);
    addArc(j, i, capacity, cost);
  }
  pair<Cost, Flow> minimumCostMaximumFlow(Index s, Index t,
                                          Flow f = kInfCapacity,
                                          bool useSPFA = false) {
    int n = g.size();
    vector<Cost> dist(n);
    vector<Index> prev(n);
    vector<Index> prev_edge(n);
    pair<Cost, Flow> total = make_pair(0, 0);
    vector<Cost> potential(n);
    while (f > 0) {
      fill(dist.begin(), dist.end(), kInfCost);
      if (useSPFA || total.second == 0) {
        deque<Index> q;
        q.push_back(s);
        dist[s] = 0;
        vector<bool> inqueue(n);
        while (!q.empty()) {
          Index i = q.front();
          q.pop_front();
          inqueue[i] = false;
          for (Index ei = 0; ei < g[i].size(); ei++) {
            const Edge &e = g[i][ei];
            Index j = e.d;
            Cost d = dist[i] + e.cost;
            if (e.capacity > 0 && d < dist[j]) {
              if (!inqueue[j]) {
                inqueue[j] = true;
                q.push_back(j);
              }
              dist[j] = d;
              prev[j] = i;
              prev_edge[j] = ei;
            }
          }
        }
      } else {
        vector<bool> vis(n);
        priority_queue<pair<Cost, Index>> q;
        q.push(make_pair(-0, s));
        dist[s] = 0;
        while (!q.empty()) {
          Index i = q.top().second;
          q.pop();
          if (vis[i])
            continue;
          vis[i] = true;
          for (Index ei = 0; ei < (Index)g[i].size(); ei++) {
            const Edge &e = g[i][ei];
            if (e.capacity <= 0)
              continue;
            Index j = e.d;
            Cost d = dist[i] + e.cost + potential[i] - potential[j];
            if (dist[j] > d) {
              dist[j] = d;
              prev[j] = i;
              prev_edge[j] = ei;
              q.push(make_pair(-d, j));
            }
          }
        }
      }
      if (dist[t] == kInfCost)
        break;
      if (!useSPFA)
        for (Index i = 0; i < n; i++)
          potential[i] += dist[i];

      Flow d = f;
      Cost distt = 0;
      for (Index v = t; v != s;) {
        Index u = prev[v];
        const Edge &e = g[u][prev_edge[v]];
        d = min(d, e.capacity);
        distt += e.cost;
        v = u;
      }
      f -= d;
      total.first += d * distt;
      total.second += d;
      for (Index v = t; v != s; v = prev[v]) {
        Edge &e = g[prev[v]][prev_edge[v]];
        e.capacity -= d;
        g[e.d][e.s].capacity += d;
      }
    }
    return total;
  }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  for (int N, M, L; cin >> N >> M >> L && N;) {
    vector<vector<int>> g(N, vector<int>(N, INF));
    rep(i, 0, M) {
      int u, v, d;
      cin >> u >> v >> d;
      g[u][v] = g[v][u] = d;
    }
    rep(i, 0, N) g[i][i] = 0;
    rep(k, 0, N) rep(i, 0, N) rep(j, 0, N) {
      if (g[i][k] != INF && g[k][j] != INF)
        g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
    }

    vector<int> p(L), t(L);
    rep(i, 0, L) { cin >> p[i] >> t[i]; }
    MinimumCostMaximumFlow mcf;
    mcf.init(L + L + 2);
    int source = L + L, sink = source + 1;
    rep(i, 0, L) {
      rep(j, 0, L) {
        if (i == j)
          continue;
        if (g[p[i]][p[j]] <= t[j] - t[i]) {
          mcf.addArc(i, L + j, 1, -1);
        }
      }
    }
    rep(i, 0, L) {
      mcf.addArc(source, i, 1, 0);
      mcf.addArc(i, sink, 1, 0);
      mcf.addArc(L + i, sink, 1, 0);
    }
    auto ans = L + mcf.minimumCostMaximumFlow(source, sink, L).first;
    cout << ans << endl;
  }
  return 0;
}