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

#pragma GCC optimize "O3"

#include <bits/stdc++.h>

using namespace std;

constexpr int N = 1e4 + 10, INF = INT_MAX / 4;

class BipartiteMatching { // O( ( V + E ) * sqrt( V ) )
public:
  vector<int> G[N]; // N = total number of nodes = n + m
  int n, m, match[N], dist[N];
  // n: number of nodes on left side, nodes are numbered 1 to n
  // m: number of nodes on right side, nodes are numbered n+1 to n+m
  // G = NIL[0] ??? G1[G[1---n]] ??? G2[G[n+1---n+m]]
  bool BFS() {
    queue<int> Q;
    for (int i = 1; i <= n; i++) {
      if (match[i] == 0) {
        dist[i] = 0;
        Q.push(i);
      } else
        dist[i] = INF;
    }
    dist[0] = INF;
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      if (u != 0)
        for (int v : G[u])
          if (dist[match[v]] == INF) {
            dist[match[v]] = dist[u] + 1;
            Q.push(match[v]);
          }
    }
    return (dist[0] != INF);
  }
  bool DFS(int u) {
    if (u != 0) {
      for (int v : G[u])
        if (dist[match[v]] == dist[u] + 1 and DFS(match[v])) {
          match[v] = u;
          match[u] = v;
          return true;
        }
      dist[u] = INF;
      return false;
    }
    return true;
  }
  int Solve() {
    int matching = 0;
    fill_n(match, n + m + 1, 0);
    while (BFS())
      for (int i = 1; i <= n; i++)
        if (match[i] == 0 and DFS(i))
          matching++;
    return matching;
  }
  void AddEdge(int u, int v) { G[u].push_back(n + v); }
} ob;

int main() {
  int E;
  scanf("%d %d %d", &ob.n, &ob.m, &E);
  for (int i = 0; i < E; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    ob.AddEdge(x + 1, y + 1);
  }
  printf("%d\\n", ob.Solve());
}

Error: TLE

Fixed submission:

#pragma GCC optimize "O3"

#include <bits/stdc++.h>

using namespace std;
// O( ( V + E ) * sqrt( V ) )
class BipartiteMatching {
public:
  static const int N = 1e4 + 10; // total number of nodes, n + m
  static const int NIL = 0;      // non-negative number (null vertex)
  static const int INF = (1 << 28);
  vector<int> G[N];
  int n, m, match[N], dist[N];
  // n: number of nodes on left side, nodes are numbered 1 to n
  // m: number of nodes on right side, nodes are numbered n+1 to n+m
  // G = NIL[0] ??? G1[G[1---n]] ??? G2[G[n+1---n+m]]
  bool BFS() {
    queue<int> Q;
    for (int i = 1; i <= n; i++) {
      if (match[i] == NIL) {
        dist[i] = 0;
        Q.push(i);
      } else
        dist[i] = INF;
    }
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      if (u != NIL)
        for (int v : G[u]) {
          if (dist[match[v]] == INF) {
            dist[match[v]] = dist[u] + 1;
            Q.push(match[v]);
          }
        }
    }
    return (dist[NIL] != INF);
  }
  bool DFS(int u) {
    if (u != NIL) {
      for (int v : G[u]) {
        if (dist[match[v]] == dist[u] + 1) {
          if (DFS(match[v])) {
            match[v] = u;
            match[u] = v;
            return true;
          }
        }
      }
      dist[u] = INF;
      return false;
    }
    return true;
  }
  int Solve() {
    dist[NIL] = INF;
    int matching = 0;
    for (int i = 0; i <= n + m; ++i)
      match[i] = NIL;
    while (BFS())
      for (int i = 1; i <= n; i++)
        if (match[i] == NIL && DFS(i))
          matching++;
    return matching;
  }
  void AddEdge(int u, int v) { G[u].push_back(n + v); }
} ob;

int main() {
  int E;
  scanf("%d %d %d", &ob.n, &ob.m, &E);
  for (int i = 0; i < E; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    ob.AddEdge(x + 1, y + 1);
  }
  printf("%d\\n", ob.Solve());
}