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

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

const int M = 1000000007;

typedef pair<int, int> P;
struct edge {
  int to, cap, cost, rev;
};

int V;
vector<edge> G[3010];
int h[3010];
int dist[3010];
int prevv[3010], preve[3010];
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;
  fill(h, h + V, 0);
  while (f > 0) {
    priority_queue<P, vector<P>, greater<P>> q;
    fill(dist, dist + V, M);
    dist[s] = 0;
    q.push(P(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 < (int)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;
          q.push(P(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == M)
      break;
    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;
    if (d * h[t] >= 0)
      break;
    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 main() {
  int n;
  cin >> n;
  vector<vector<int>> a(n, vector<int>(2));
  int cnt[1000010] = {};
  for (int i = 0; i < n; ++i) {
    cin >> a[i][0] >> a[i][1];
    if (a[i][0] > a[i][1]) {
      int t = a[i][0];
      a[i][0] = a[i][1];
      a[i][1] = t;
    }
    ++cnt[a[i][0]];
    ++cnt[a[i][1]];
  }
  int lc = 0;
  int ind[1000010];
  for (int i = 0; i < 1000010; ++i) {
    if (cnt[i])
      ind[i] = lc++;
  }
  V = n + lc + 2;
  for (int i = 0; i < lc; ++i) {
    add_edge(n + i, n + lc + 1, 1, 0);
  }
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    add_edge(n + lc, i, 1, 0);
    add_edge(i, n + ind[a[i][0]], 1, -a[i][1]);
    add_edge(i, n + ind[a[i][1]], 1, -a[i][0]);
  }
  cout << (ans - min_cost_flow(n + lc, n + lc + 1, n)) << "\\n";
  return 0;
}

Error: TLE

Fixed submission:

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

const int M = 1000000007;

typedef pair<int, int> P;
struct edge {
  int to, cap, cost, rev;
};

int V;
vector<edge> G[3010];
int h[3010];
int dist[3010];
int prevv[3010], preve[3010];
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;
  fill(h, h + V, 0);
  while (f > 0) {
    priority_queue<P, vector<P>, greater<P>> q;
    fill(dist, dist + V, M);
    dist[s] = 0;
    q.push(P(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 < (int)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;
          q.push(P(dist[e.to], e.to));
        }
      }
    }
    if (dist[t] == M)
      return M;
    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 main() {
  int n;
  cin >> n;
  vector<vector<int>> a(n, vector<int>(2));
  int cnt[1000010] = {};
  for (int i = 0; i < n; ++i) {
    cin >> a[i][0] >> a[i][1];
    if (a[i][0] > a[i][1]) {
      int t = a[i][0];
      a[i][0] = a[i][1];
      a[i][1] = t;
    }
    ++cnt[a[i][0]];
    ++cnt[a[i][1]];
  }
  int lc = 0;
  int ind[1000010];
  for (int i = 0; i < 1000010; ++i) {
    if (cnt[i])
      ind[i] = lc++;
  }
  V = n + lc + 2;
  for (int i = 0; i < lc; ++i) {
    add_edge(n + i, n + lc + 1, 1, 0);
  }
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    add_edge(n + lc, i, 1, 0);
    if (cnt[a[i][0]] == 1) {
      ans += a[i][1];
      continue;
    }
    add_edge(i, n + ind[a[i][0]], 1, -a[i][1]);
    add_edge(i, n + ind[a[i][1]], 1, -a[i][0]);
  }
  while (1) {
    int d = -min_cost_flow(n + lc, n + lc + 1, 1);
    if (d <= 0) {
      cout << ans << "\\n";
      return 0;
    }
    ans += d;
  }
}