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

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> P;

#define INF 1000000000

struct Edge {
  int to, cap, cost, rev;
};

vector<vector<Edge>> G;

int dist[4000], h[4000] = {0}, prevV[4000], prevE[4000];
int flow(int s, int t, int f) {
  int res = 0;
  while (f > 0) {
    fill(&dist[0], &dist[0] + 4000, INF);
    dist[s] = 0;
    priority_queue<P, vector<P>, greater<P>> Q;
    Q.push({0, s});
    while (!Q.empty()) {
      P p = Q.top();
      Q.pop();
      int v = p.second;
      if (dist[v] < p.first)
        continue;
      for (int i = 0; i < G[v].size(); ++i) {
        Edge &e = G[v][i];
        if (e.cap > 0 && dist[v] + e.cost + h[v] - h[e.to] < dist[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevV[e.to] = v;
          prevE[e.to] = i;
          Q.push({dist[e.to], e.to});
        }
      }
    }
    if (dist[t] == INF) {
      cout << "ERROR: f=" << f << endl;
      exit(1);
    }
    for (int i = 0; i < G.size(); ++i)
      h[i] += dist[i];

    int d = f;
    for (int v = t; v != s; v = prevV[v]) {
      d = min(d, G[prevV[v]][prevE[v]].cap);
    }
    f -= d;
    res += d * h[t];
    for (int v = t; v != s; v = prevV[v]) {
      Edge &e = G[prevV[v]][prevE[v]];
      e.cap -= d;
      G[e.to][e.rev].cap += d;
    }
  }
  return res;
}
void addEdge(int from, int to, int cap, int cost) {
  G[from].push_back({to, cap, cost, (int)G[to].size()});
  G[to].push_back({from, 0, -cost, (int)G[from].size() - 1});
}

int main() {
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (int i = 0; i < N; ++i) {
    cin >> A[i] >> B[i];
  }
  map<int, int> m;
  int msz = 0;
  for (int i = 0; i < N; ++i) {
    if (m.find(A[i]) == m.end()) {
      m[A[i]] = msz++;
    }
  }
  for (int i = 0; i < N; ++i) {
    if (m.find(B[i]) == m.end()) {
      m[B[i]] = msz++;
    }
  }

  int s = msz + N, t = s + 1;
  G.resize(t + 1);

  for (int i = 0; i < N; ++i) {
    addEdge(m[A[i]], msz + i, 1, -B[i]);
    addEdge(m[B[i]], msz + i, 1, -A[i]);
    addEdge(msz + i, t, 1, 0);
  }
  for (int i = 0; i < msz; ++i) {
    addEdge(s, i, 1, 0);
    addEdge(i, t, 1, 0);
  }

  cout << -flow(s, t, msz) << endl;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> P;

#define INF 1000000000

struct Edge {
  int to, cap, cost, rev;
};

vector<vector<Edge>> G;

int dist[4000], h[4000] = {0}, prevV[4000], prevE[4000];
int flow(int s, int t, int f) {
  int res = 0;
  while (f > 0) {
    fill(&dist[0], &dist[0] + 4000, INF);
    dist[s] = 0;
    priority_queue<P> Q;
    Q.push({0, s});
    while (!Q.empty()) {
      P p = Q.top();
      Q.pop();
      int v = p.second;
      for (int i = 0; i < G[v].size(); ++i) {
        Edge &e = G[v][i];
        if (e.cap > 0 && dist[v] + e.cost + h[v] - h[e.to] < dist[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevV[e.to] = v;
          prevE[e.to] = i;
          Q.push({dist[e.to], e.to});
        }
      }
    }
    for (int i = 0; i < G.size(); ++i)
      h[i] += dist[i];

    int d = f;
    for (int v = t; v != s; v = prevV[v]) {
      d = min(d, G[prevV[v]][prevE[v]].cap);
    }
    f -= d;
    res += d * h[t];
    for (int v = t; v != s; v = prevV[v]) {
      Edge &e = G[prevV[v]][prevE[v]];
      e.cap -= d;
      G[e.to][e.rev].cap += d;
    }
  }
  return res;
}
void addEdge(int from, int to, int cap, int cost) {
  G[from].push_back({to, cap, cost, (int)G[to].size()});
  G[to].push_back({from, 0, -cost, (int)G[from].size() - 1});
}

int main() {
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (int i = 0; i < N; ++i) {
    cin >> A[i] >> B[i];
  }
  map<int, int> m;
  int msz = 0;
  for (int i = 0; i < N; ++i) {
    if (m.find(A[i]) == m.end()) {
      m[A[i]] = msz++;
    }
  }
  for (int i = 0; i < N; ++i) {
    if (m.find(B[i]) == m.end()) {
      m[B[i]] = msz++;
    }
  }

  int s = msz + N, t = s + 1;
  G.resize(t + 1);

  for (int i = 0; i < N; ++i) {
    addEdge(m[A[i]], N + i, 1, -B[i]);
    addEdge(m[B[i]], N + i, 1, -A[i]);
    addEdge(N + i, t, 1, 0);
  }
  for (int i = 0; i < msz; ++i) {
    addEdge(s, i, 1, 0);
    addEdge(i, t, 1, 0);
  }

  cout << -flow(s, t, msz) << endl;
}