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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x, s, g) ((x) >= (s) && (x) < (g))
#define ISIN(x, y, w, h) (IN((x), 0, (w)) && IN((y), 0, (h)))
#define print(x) printf("%d\\n", x)

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int _dx[] = {0, 1, 0, -1};
const int _dy[] = {-1, 0, 1, 0};

int getInt() {
  int ret = 0, c;
  c = getchar();
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

vector<vector<int>> g;
int n, m;

vector<bool> visited;
vector<int> matching;

bool augment(int left) {
  if (left < 0)
    return true;
  if (visited[left])
    return false;
  visited[left] = true;
  REP(i, g[left].size()) {
    int right = g[left][i];
    if (augment(matching[right])) {
      matching[right] = left;
      return true;
    }
  }
  return false;
}
int match() {
  matching.assign(m, -1);
  int matches = 0;
  REP(left, n) {
    visited.assign(n, false);
    if (augment(left))
      matches++;
  }
  return matches;
}

int gcd(int a, int b) {
  if (a > b)
    swap(a, b);
  if (a == 0)
    return b;
  return gcd(a, b % a);
}

int main() {
  int r[500];
  int b[500];
  while ((n = getInt()) + (m = getInt())) {
    g = vector<vector<int>>(n);
    visited = vector<bool>(n);
    matching = vector<int>(m);

    REP(i, n)
    b[i] = getInt();

    REP(i, m)
    r[i] = getInt();

    REP(i, n) REP(j, m) if (gcd(b[i], r[j]) != 1) { g[i].push_back(j); }

    print(match());
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define f first
#define s second
#define mp make_pair

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define rep(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define ALL(c) (c).begin(), (c).end()
#define IN(x, s, g) ((x) >= (s) && (x) < (g))
#define ISIN(x, y, w, h) (IN((x), 0, (w)) && IN((y), 0, (h)))
#define print(x) printf("%d\\n", x)

using namespace std;

typedef unsigned int uint;
typedef long long ll;

const int _dx[] = {0, 1, 0, -1};
const int _dy[] = {-1, 0, 1, 0};

int getInt() {
  int ret = 0, c;
  c = getchar();
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

typedef vector<vector<char>> G;

int flow(G &g, int s, int d) {
  int n = g.size();
  int ans = 0;

  while (true) {
    vector<int> prevs(n, -1);
    queue<int> q;
    bool ok = false;

    prevs[s] = n;
    q.push(s);
    while (!q.empty()) {
      int now = q.front();
      q.pop();
      if (now == d) {
        ok = true;
        break;
      }
      for (int i = 0; i < n; i++) {
        if (g[now][i] > 0) {
          if (prevs[i] == -1) {
            prevs[i] = now;
            q.push(i);
          }
        }
      }
    }

    if (!ok)
      return ans;

    int f = 1;

    int pos = d;
    while (pos != s) {
      int pos2 = prevs[pos];
      g[pos2][pos] -= f;
      g[pos][pos2] += f;
      pos = pos2;
    }
    ans += f;
  }
}

int gcd(int a, int b) {
  if (a > b)
    swap(a, b);
  if (a == 0)
    return b;
  return gcd(a, b % a);
}

int main() {
  int m, n;
  int r[500];
  int b[500];
  while ((m = getInt()) + (n = getInt())) {
    vector<vector<char>> g(n + m + 2, vector<char>(n + m + 2, 0));

    REP(i, m) {
      b[i] = getInt();
      g[n + m][i] = 1;
    }
    REP(i, n) {
      r[i] = getInt();
      g[m + i][n + m + 1] = 1;
    }

    REP(i, m) REP(j, n) if (gcd(b[i], r[j]) != 1) g[i][m + j] = 1;

    print(flow(g, n + m, n + m + 1));
  }
  return 0;
}