Problem p00744 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

#define REP(i, a, b) for (i = a; i < b; ++i)
#define rep(i, n) REP(i, 0, n)

int b[501], r[501], m, n;
int primes[10050];
vector<int> G[1001];

int gcd(int x, int y) {
  if (y == 0)
    return x;
  return gcd(y, x % y);
}

bool bfs(vector<int> &pair_v, vector<int> &dist) {
  queue<int> Q;
  const int NIL = n + m;
  fill(dist.begin(), dist.end(), 1 << 29);
  for (int i = 0; i < n + m; ++i)
    if (pair_v[i] == NIL) {
      dist[i] = 0;
      Q.push(i);
    }

  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    if (v != NIL) {
      for (int i = 0; i < G[v].size(); ++i) {
        if (dist[pair_v[G[v][i]]] == 1 << 29) {
          dist[pair_v[G[v][i]]] = dist[v] + 1;
          Q.push(pair_v[G[v][i]]);
        }
      }
    }
  }
  return dist[NIL] != 1 << 29;
}

bool dfs(int v, vector<int> &pair_v, vector<int> &dist) {
  const int NIL = n + m;
  if (v != NIL) {
    for (int i = 0; i < G[v].size(); ++i) {
      int u = G[v][i];
      if (dist[pair_v[u]] == dist[v] + 1) {
        if (dfs(pair_v[u], pair_v, dist)) {
          pair_v[u] = v;
          pair_v[v] = u;
          return true;
        }
      }
    }
    dist[v] = 1 << 29;
    return false;
  }
  return true;
}

int biparate_matching() {
  vector<int> pair_v(n + m + 1, n + m); // NIL == n+m
  vector<int> dist(n + m + 1);
  int matching = 0;
  int bc = 0;
  while (bfs(pair_v, dist)) {
    // cout<<"bfs : "<<bc<<endl;
    bc++;
    for (int i = 0; i < n + m; ++i) {
      if (pair_v[i] == n + m)
        if (dfs(i, pair_v, dist)) {
          matching++;
        }
    }
  }
  return matching;
}

int main() {
  int i, j;
  while (cin >> m >> n, m | n) {
    rep(i, m) cin >> b[i];
    rep(i, n) cin >> r[i];

    rep(i, n + m) G[i].clear();
    rep(i, m) rep(j, n) {
      if (gcd(b[i], r[j]) > 1) {
        G[i].push_back(j + m);
        G[j + m].push_back(i);
        // cout<<"add edge "<<i<<" "<<j<<endl;
      }
    }

    // cout<<"let's matching"<<endl;

    cout << biparate_matching() << endl;
  }
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

#define REP(i, a, b) for (i = a; i < b; ++i)
#define rep(i, n) REP(i, 0, n)

int b[501], r[501], m, n;
int primes[10001];
vector<int> G[1001];

void make_prime() {
  memset(primes, 0, sizeof(primes));
  primes[0] = primes[1] = 1;
  for (int i = 4; i <= 10000; i += 2)
    primes[i] = 1;
  for (int i = 3; i * i <= 10000; i += 2)
    if (primes[i] == 0)
      for (int j = 2; i * j <= 10000; ++j)
        primes[i * j] = 1;
}

vector<int> factorize(const int xx) {
  int x = xx;
  vector<int> factor;

  if (x % 2 == 0)
    factor.push_back(2);
  while (x % 2 == 0)
    x /= 2;

  if (primes[x] == 0) {
    factor.push_back(x);
    return factor;
  }

  for (int i = 3; i <= xx; i += 2) {
    if (x == 1)
      break;
    if (primes[i])
      continue;
    if (x % i == 0)
      factor.push_back(i);
    while (x % i == 0)
      x /= i;
  }
  sort(factor.begin(), factor.end());
  return factor;
}

bool iscon(const int i, const int j, const vector<vector<int>> &fact) {
  for (int x = 0, y = 0; x < fact[i].size() && y < fact[j + m].size();) {
    if (fact[i][x] == fact[j + m][y])
      return true;
    if (fact[i][x] > fact[j + m][y])
      y++;
    else
      x++;
  }
  return false;
}

bool bfs(vector<int> &pair_v, vector<int> &dist) {
  queue<int> Q;
  const int NIL = n + m;
  fill(dist.begin(), dist.end(), 1 << 29);
  for (int i = 0; i < n + m; ++i)
    if (pair_v[i] == NIL) {
      dist[i] = 0;
      Q.push(i);
    }

  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    if (v != NIL) {
      for (int i = 0; i < G[v].size(); ++i) {
        if (dist[pair_v[G[v][i]]] == 1 << 29) {
          dist[pair_v[G[v][i]]] = dist[v] + 1;
          Q.push(pair_v[G[v][i]]);
        }
      }
    }
  }
  return dist[NIL] != 1 << 29;
}

bool dfs(int v, vector<int> &pair_v, vector<int> &dist) {
  const int NIL = n + m;
  if (v != NIL) {
    for (int i = 0; i < G[v].size(); ++i) {
      int u = G[v][i];
      if (dist[pair_v[u]] == dist[v] + 1) {
        if (dfs(pair_v[u], pair_v, dist)) {
          pair_v[u] = v;
          pair_v[v] = u;
          return true;
        }
      }
    }
    dist[v] = 1 << 29;
    return false;
  }
  return true;
}

int biparate_matching() {
  vector<int> pair_v(n + m + 1, n + m); // NIL == n+m
  vector<int> dist(n + m + 1);
  int matching = 0;
  int bc = 0;
  while (bfs(pair_v, dist)) {
    // cout<<"bfs : "<<bc<<endl;
    bc++;
    for (int i = 0; i < n + m; ++i) {
      if (pair_v[i] == n + m)
        if (dfs(i, pair_v, dist)) {
          matching++;
        }
    }
  }
  return matching;
}

int main() {
  int i, j;
  make_prime();
  while (cin >> m >> n, m | n) {
    rep(i, m) cin >> b[i];
    rep(i, n) cin >> r[i];

    vector<vector<int>> fact(n + m, vector<int>(0));
    rep(i, m) fact[i] = factorize(b[i]);
    rep(i, n) fact[i + m] = factorize(r[i]);

    // cout<<"end factorize"<<endl;

    // rep(i,n+m) {
    //     cout<<i<<" ";
    //     rep(j,fact[i].size()) cout<<fact[i][j]<<" ";
    //     cout<<endl;
    // }

    rep(i, n + m) G[i].clear();
    rep(i, m) rep(j, n) {
      if (iscon(i, j, fact)) {
        G[i].push_back(j + m);
        G[j + m].push_back(i);
        // cout<<"add edge "<<i<<" "<<j<<endl;
      }
    }

    // cout<<"let's matching"<<endl;

    cout << biparate_matching() << endl;
  }
}