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

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX / 3
#define mod 1000000007

#define MAX_V 4000

typedef pair<int, int> P;

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

int V;
vector<edge> g[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void init(int v) {
  V = v;
  for (int i = 0; i < MAX_V; i++) {
    g[i].clear();
  }
}

void add_edge(int from, int to, int cap, int cost) {
  g[from].push_back((edge){to, cap, cost, (int)g[to].size()});
  g[to].push_back((edge){from, 0, -cost, (int)g[from].size() - 1});
}

int min_cost_flow(int s, int t, int f) {
  int res = 0;
  memset(h, 0, sizeof(h));
  while (f > 0) {
    priority_queue<P, vector<P>, greater<P>> que;
    fill(dist, dist + V, INF);
    dist[s] = 0;
    que.push(P(0, s));
    while (que.size()) {
      P p = que.top();
      que.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[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          que.push(P(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == INF)
      return -1;
    for (int v = 0; v < V; v++)
      h[v] += dist[v];

    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[v][e.rev].cap += d;
    }
  }
  return res;
}

int n, a[1000], b[1000];
vector<int> vs;

int main() {
  scanf("%d", &n);
  rep(i, n) scanf("%d%d", a + i, b + i);
  rep(i, n) {
    vs.push_back(a[i]);
    vs.push_back(b[i]);
  }
  sort(all(vs));
  uni(vs);

  int m = vs.size();
  int src = m + n, dest = m + n + 1;
  init(m + n + 2);
  rep(i, m) { add_edge(src, i, 1, 0); }
  rep(i, n) {
    int f1, f2;
    f1 = lower_bound(all(vs), a[i]) - vs.begin();
    f2 = lower_bound(all(vs), b[i]) - vs.begin();
    add_edge(f1, i + m, 1, -b[i]);
    add_edge(f2, i + m, 1, -a[i]);
    add_edge(i + m, dest, 1, 0);
  }
  add_edge(src, dest, n, 0);

  cout << -min_cost_flow(src, dest, n) << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX / 3
#define mod 1000000007

#define MAX_V 10000

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

int V;
vector<edge> g[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void init(int v) {
  V = v;
  for (int i = 0; i < MAX_V; i++) {
    g[i].clear();
  }
}

void add_edge(int from, int to, int cap, int cost) {
  g[from].push_back((edge){to, cap, cost, (int)g[to].size()});
  g[to].push_back((edge){from, 0, -cost, (int)g[from].size() - 1});
}

int min_cost_flow(int s, int t, int f) {
  int res = 0;
  memset(h, 0, sizeof(h));
  while (f > 0) {
    fill(dist, dist + V, INF);
    dist[s] = 0;
    bool update = true;
    while (update) {
      update = false;
      for (int v = 0; v < V; v++) {
        if (dist[v] == INF)
          continue;
        for (int i = 0; i < g[v].size(); i++) {
          edge &e = g[v][i];
          if (e.cap > 0 && dist[e.to] > dist[v] + e.cost) {
            dist[e.to] = dist[v] + e.cost;
            prevv[e.to] = v;
            preve[e.to] = i;
            update = true;
          }
        }
      }
    }
    if (dist[t] == INF)
      return INF;

    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 * dist[t];
    for (int v = t; v != s; v = prevv[v]) {
      edge &e = g[prevv[v]][preve[v]];
      e.cap -= d;
      g[v][e.rev].cap += d;
    }
  }
  return res;
}

int n, a[1000], b[1000];
vector<int> vs;

int main() {
  cin >> n;
  rep(i, n) cin >> a[i] >> b[i];
  rep(i, n) {
    vs.push_back(a[i]);
    vs.push_back(b[i]);
  }
  sort(all(vs));
  uni(vs);

  int m = vs.size();
  int src = m + n, dest = m + n + 1;
  init(m + n + 2);
  rep(i, m) { add_edge(src, i, 1, 0); }
  rep(i, n) {
    int f1, f2;
    f1 = lower_bound(all(vs), a[i]) - vs.begin();
    f2 = lower_bound(all(vs), b[i]) - vs.begin();
    add_edge(f1, i + m, 1, -b[i]);
    add_edge(f2, i + m, 1, -a[i]);
    add_edge(i + m, dest, 1, 0);
  }
  add_edge(src, dest, n, 0);

  cout << -min_cost_flow(src, dest, n) << endl;

  return 0;
}