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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)n; (i)++)
#define foreach(i, c)                                                          \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

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

const int SIZE = 1002;
int V;
vector<int> G[1002];
int match[1002];
bool used[1002];

void init(int v) {
  int i;
  fill(used, used + SIZE, false);
  fill(match, match + SIZE, 0);
  rep(i, SIZE) G[i].clear();
  V = v;
}

void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
}

bool dfs(int v) {
  int i;
  used[v] = true;
  rep(i, G[v].size()) {
    int u = G[v][i], w = match[u];
    if (w < 0 || !used[w] && dfs(w)) {
      match[v] = u;
      match[u] = v;
      return true;
    }
  }
  return false;
}

int bipartite_matching() {
  int v, res = 0;
  memset(match, -1, sizeof match);
  rep(v, V) {
    if (match[v] < 0) {
      memset(used, 0, sizeof used);
      if (dfs(v)) {
        res++;
      }
    }
  }
  return res;
}

int m, n;
int b[502], r[502];
const int MAX_N = 10000000;

int main() {
  int i, j, k;

  while (scanf("%d%d", &m, &n), m | n) {
    rep(i, m) scanf("%d", &b[i]);
    rep(i, n) scanf("%d", &r[i]);

    init(m + n);
    rep(i, m) {
      rep(j, n) {
        if (gcd(b[i], r[j]) != 1)
          add_edge(i, m + j);
      }
    }

    printf("%d\\n", bipartite_matching());
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)n; (i)++)
#define foreach(i, c)                                                          \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

const int SIZE = 1002;
int V;
vector<int> G[1002];
int match[1002];
bool used[1002];

void init(int v) {
  int i;
  fill(used, used + SIZE, false);
  fill(match, match + SIZE, 0);
  rep(i, SIZE) G[i].clear();
  V = v;
}

void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
}

bool dfs(int v) {
  int i;
  used[v] = true;
  rep(i, G[v].size()) {
    int u = G[v][i], w = match[u];
    if (w < 0 || !used[w] && dfs(w)) {
      match[v] = u;
      match[u] = v;
      return true;
    }
  }
  return false;
}

int bipartite_matching() {
  int v, res = 0;
  memset(match, -1, sizeof match);
  rep(v, V) {
    if (match[v] < 0) {
      memset(used, 0, sizeof used);
      if (dfs(v)) {
        res++;
      }
    }
  }
  return res;
}

int m, n;
int b[502], r[502];
const int MAX_N = 10000000;
//  但多
bool check[MAX_N];
vector<int> prime;

int main() {
  int i, j, k;
  // 但多
  fill(check, check + MAX_N, true);
  for (i = 4; i < MAX_N; i += 2)
    check[i] = false;
  prime.push_back(2);
  for (i = 3; i < MAX_N; i += 2)
    if (check[i]) {
      prime.push_back(i);
      for (j = i + i; j < MAX_N; j += i)
        check[j] = false;
    }

  while (scanf("%d%d", &m, &n), m | n) {
    rep(i, m) scanf("%d", &b[i]);
    rep(i, n) scanf("%d", &r[i]);

    init(m + n);
    rep(i, m) {
      rep(j, n) {
        for (k = 0; prime[k] <= b[i] && prime[k] <= r[j]; k++) {
          if (b[i] % prime[k] == 0 && r[j] % prime[k] == 0) {
            add_edge(i, m + j);
            // printf("%d %d\\n", i, j);
            break;
          }
        }
      }
    }

    printf("%d\\n", bipartite_matching());
  }
  return 0;
}