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

#include <bits/stdc++.h>
using namespace std;
#define MAX_V 1000000
#define INF 1e9

int gcd(int a, int b) {

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

// 辺を表す構造体　(行先、容量、逆辺の場所)
struct edge {
  int to, cap, rev;
};

// vector<vector<edge> > G(MAX_V);       //グラフの隣接リスト表現
bool used[MAX_V]; // DFSですでに調べたかのグラフ

// from から to へ向かう容量 cap の辺をグラフに張る
void add_edge(int from, int to, int cap, vector<vector<edge>> &G) {

  edge F;
  edge T;
  F.to = to;
  F.cap = cap;
  F.rev = G[to].size();
  G[from].push_back(F);

  T.to = from;
  T.cap = 0;
  T.rev = G[from].size() - 1;
  G[to].push_back(T);
}

// 増加パスをDFSで探す
int dfs(int v, int t, int f, vector<vector<edge>> &G) {
  if (v == t)
    return f;
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    edge &e = G[v][i]; // すごい
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap), G);
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d; // もっとすごい
        return d;
      }
    }
  }
  return 0;
}

// s から t への最大流を求める
int max_flow(int s, int t, vector<vector<edge>> &G) {
  int flow = 0;
  while (1) {
    memset(used, 0, sizeof(used));
    int f = dfs(s, t, INF, G);
    if (f == 0)
      return flow;
    flow += f;
  }
}

int main() {

  while (1) {

    int m, n;
    cin >> m >> n;
    if (!m)
      break;

    vector<vector<edge>> G(MAX_V);
    vector<int> b(m);
    vector<int> r(n);
    for (int i = 0; i < m; i++)
      cin >> b[i];
    for (int i = 0; i < n; i++)
      cin >> r[i];

    // 入力
    // xはuに属する
    // yはvに属する
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        if (gcd(b[i], r[j]) != 1) {
          int x = i + 1;
          int y = j + 1;
          y += m;
          add_edge(x, y, 1, G);
        }
      }
    }

    for (int i = 1; i <= m; i++)
      add_edge(0, i, 1, G);
    for (int i = m + 1; i <= m + n; i++)
      add_edge(i, m + n + 1, 1, G);

    cout << max_flow(0, m + n + 1, G) << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define MAX_V 1000000
#define INF 1e9

int gcd(int a, int b) {

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

// 辺を表す構造体　(行先、容量、逆辺の場所)
struct edge {
  int to, cap, rev;
};

vector<vector<edge>> G(MAX_V); // グラフの隣接リスト表現
bool used[MAX_V];              // DFSですでに調べたかのグラフ

// from から to へ向かう容量 cap の辺をグラフに張る
void add_edge(int from, int to, int cap) {

  edge F;
  edge T;
  F.to = to;
  F.cap = cap;
  F.rev = G[to].size();
  G[from].push_back(F);

  T.to = from;
  T.cap = 0;
  T.rev = G[from].size() - 1;
  G[to].push_back(T);
}

// 増加パスをDFSで探す
int dfs(int v, int t, int f) {
  if (v == t)
    return f;
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    edge &e = G[v][i]; // すごい
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d; // もっとすごい
        return d;
      }
    }
  }
  return 0;
}

// s から t への最大流を求める
int max_flow(int s, int t) {
  int flow = 0;
  while (1) {
    memset(used, 0, sizeof(used));
    int f = dfs(s, t, INF);
    if (f == 0)
      return flow;
    flow += f;
  }
}

int main() {

  while (1) {
    int m, n;
    cin >> m >> n;
    if (!m)
      break;
    vector<int> b(m);
    vector<int> r(n);
    for (int i = 0; i < m; i++)
      cin >> b[i];
    for (int i = 0; i < n; i++)
      cin >> r[i];

    // 入力
    // xはuに属する
    // yはvに属する
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        if (gcd(b[i], r[j]) != 1) {
          int x = i + 1;
          int y = j + 1;
          y += m;
          add_edge(x, y, 1);
        }
      }
    }

    for (int i = 1; i <= m; i++)
      add_edge(0, i, 1);
    for (int i = m + 1; i <= m + n; i++)
      add_edge(i, m + n + 1, 1);

    cout << max_flow(0, m + n + 1) << endl;
  }
  return 0;
}