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

#include <bits/stdc++.h>
typedef long long LL;
#define SORT(c) sort((c).begin(), (c).end())

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

using namespace std;
// edge e, G[e.to][e.rev].to=e
vector<int> blue, red;
vector<vector<int>> adj;
vector<vector<int>> F;
void addflow(int from, int to, int cap) {
  adj[from].push_back(to);
  adj[to].push_back(from);
  F[from][to] += cap;
}
void flow(int from, int to, int cap) {
  F[from][to] -= cap;
  F[to][from] += cap;
}
set<int> already;
int FF(int so, int si, int mcap) {
  // cout << "FF " << so << ' ' << si << ' ' << mcap << endl;
  if (so == si)
    return mcap;
  if (!already.insert(so).second)
    return 0;
  REP(i, adj[so].size()) {
    // cout << "FF2" << endl;
    int answer;
    if (F[so][adj[so][i]])
      if (answer = FF(adj[so][i], si, min(mcap, F[so][adj[so][i]]))) {
        flow(so, adj[so][i], answer);
        return answer;
      }
  }
  return 0;
}
int maxflow(int so, int si) {
  int answer = 0;
  already.clear();
  while (int tmp = FF(so, si, 1048576)) {
    answer += tmp;
    already.clear();
    // cout << tmp << endl;
  }
  return answer;
}
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int main(void) {
  for (;;) {
    int m, n;
    cin >> m >> n;
    if (!m && !n)
      return 0;
    blue.resize(m);
    REP(i, m) cin >> blue[i];
    red.resize(n);
    REP(i, n) cin >> red[i];
    adj.assign(m + n + 2, vector<int>());
    F.resize(m + n + 2);
    REP(i, m + n + 2) F[i].assign(m + n + 2, 0);
    REP(j, n) addflow(m + j, m + n + 1, 1);
    REP(i, m) REP(j, n) if (gcd(blue[i], red[j]) != 1) addflow(i, m + j, 1);
    REP(i, m) addflow(m + n, i, 1);
    cout << maxflow(m + n, m + n + 1) << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
typedef long long LL;
#define SORT(c) sort((c).begin(), (c).end())

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

using namespace std;
typedef struct {
  int to, cap, rev;
} edge;
// edge e, G[e.to][e.rev].to=e
vector<int> blue, red;
vector<vector<edge>> G;
void addflow(int from, int to, int cap) {
  int a = G[from].size(), b = G[to].size();
  G[from].push_back((edge){to, cap, b});
  G[to].push_back((edge){from, 0, a});
}
int flow(vector<int> trace) {
  int answer = 1048576;
  REP(i, trace.size() - 1)
  REP(j, G[trace[i]].size()) if (G[trace[i]][j].to == trace[i + 1]) answer =
      min(answer, G[trace[i]][j].cap);
  REP(i, trace.size() - 1)
  REP(j, G[trace[i]].size()) if (G[trace[i]][j].to == trace[i + 1])
      G[trace[i]][j]
          .cap -= answer,
      G[G[trace[i]][j].to][G[trace[i]][j].rev].cap += answer;
  return answer;
}
int EK(int so, int si) {
  queue<vector<int>> bfs;
  vector<int> start;
  set<int> already;
  start.push_back(so);
  bfs.push(start);
  while (!bfs.empty()) {
    vector<int> trace(bfs.front());
    bfs.pop();
    int tmp = trace.back();
    if (tmp == si)
      return flow(trace);
    if (!already.insert(tmp).second)
      continue;
    REP(i, G[tmp].size()) {
      if (!G[tmp][i].cap)
        continue;
      vector<int> nexttrace(trace);
      nexttrace.push_back(G[tmp][i].to);
      bfs.push(nexttrace);
    }
  }
  return 0;
}
int maxflow(int so, int si) {
  int answer = 0;
  while (int tmp = EK(so, si))
    answer += tmp;
  return answer;
}
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int main(void) {
  for (;;) {
    int m, n;
    cin >> m >> n;
    if (!m && !n)
      return 0;
    blue.resize(m);
    REP(i, m) cin >> blue[i];
    red.resize(n);
    REP(i, n) cin >> red[i];
    G.assign(m + n + 2, vector<edge>());
    REP(i, m) addflow(m + n, i, 1);
    REP(i, m) REP(j, n) if (gcd(blue[i], red[j]) != 1) addflow(i, m + j, 1);
    REP(j, n) addflow(m + j, m + n + 1, 1);
    cout << maxflow(m + n, m + n + 1) << endl;
  }
}