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

#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define reps(i, f, n) for (int i = f; i < int(n); i++)
#define rep(i, n) reps(i, 0, n)
#define pb push_back

const int INF = 1000000000;

typedef pair<int, int> pii;

class Edge {
public:
  int a, b, c, f;
  Edge(int a, int b, int c, int f) : a(a), b(b), c(c), f(f) {}
};

class Flow {
public:
  static const int N = 1111;
  static const int INF = 1000000000;

  vector<Edge> e[N];
  vector<pii> r[N];

  void addEdge(int a, int b, int c) {
    e[a].push_back(Edge(a, b, c, 0));
    r[b].push_back(pii(a, e[a].size() - 1));
  }
  int visit[N];
  int flow(int p, int f, int end) {
    if (p == end)
      return f;
    if (visit[p] == 1)
      return 0;
    visit[p] = 1;

    rep(i, e[p].size()) {
      int d = e[p][i].c - e[p][i].f;
      if (d > 0) {
        int val = flow(e[p][i].b, min(f, d), end);
        if (val != 0) {
          e[p][i].f += val;
          return val;
        }
      }
    }
    rep(i, r[p].size()) {
      int r1 = r[p][i].first;
      int r2 = r[p][i].second;
      int d = e[r1][r2].f;
      if (d > 0) {
        int val = flow(e[r1][r2].a, min(f, d), end);
        if (val != 0) {
          e[r1][r2].f -= val;
          return val;
        }
      }
    }
    return 0;
  }
  int solve(int start, int end) {
    int ans = 0;
    while (1) {
      rep(i, N) visit[i] = 0;
      int val = flow(start, INF, end);
      if (val == 0)
        break;
      ans += val;
    }
    return ans;
  }
};

const int S = 4000;
int sosu[S];
vector<int> prime;
int sosuInit() {
  sosu[0] = sosu[1] = 1;
  rep(i, S) {
    if (sosu[i] == 1)
      continue;
    for (int j = i * 2; j < S; j += i)
      sosu[j] = 1;
    prime.push_back(i);
  }
}

map<int, vector<int>> canop;

int main() {
  sosuInit();

A:;

  canop.clear();

  int n, m;
  cin >> n >> m;

  if (n == 0 && m == 0)
    return 0;

  Flow flow;

  rep(i, n) {
    int a;
    cin >> a;
    rep(j, prime.size()) {
      if (a % prime[j] == 0) {
        canop[prime[j]].push_back(i + 1);
        a /= prime[j];
        j--;
      }
    }
    if (a != 1)
      canop[a].push_back(i + 1);
    flow.addEdge(0, i + 1, 1);
  }

  rep(i, m) {
    int b;
    cin >> b;
    rep(j, prime.size()) {
      if (b % prime[j] == 0) {
        rep(k, canop[prime[j]].size()) {
          flow.addEdge(canop[prime[j]][k], i + n + 1, 1);
        }
        b /= prime[j];
        j--;
      }
    }
    if (b != 1) {
      rep(k, canop[b].size()) { flow.addEdge(canop[b][k], i + n + 1, 1); }
    }
    flow.addEdge(i + n + 1, n + m + 1, 1);
  }

  int ans = flow.solve(0, n + m + 1);
  printf("%d\\n", ans);

  goto A;
}
/*

4 3
2 6 6 15
2 3 5
0 0

*/

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define reps(i, f, n) for (int i = f; i < int(n); i++)
#define rep(i, n) reps(i, 0, n)
#define pb push_back

const int INF = 1000000000;

typedef pair<int, int> pii;

class Edge {
public:
  int a, b, c, f;
  Edge(int a, int b, int c, int f) : a(a), b(b), c(c), f(f) {}
};

class Flow {
public:
  static const int N = 1111;
  static const int INF = 1000000000;

  vector<Edge> e[N];
  vector<pii> r[N];

  void addEdge(int a, int b, int c) {
    e[a].push_back(Edge(a, b, c, 0));
    r[b].push_back(pii(a, e[a].size() - 1));
  }
  int visit[N];
  int flow(int p, int f, int end) {
    if (p == end)
      return f;
    if (visit[p] == 1)
      return 0;
    visit[p] = 1;

    rep(i, e[p].size()) {
      int d = e[p][i].c - e[p][i].f;
      if (d > 0) {
        int val = flow(e[p][i].b, min(f, d), end);
        if (val != 0) {
          e[p][i].f += val;
          return val;
        }
      }
    }
    rep(i, r[p].size()) {
      int r1 = r[p][i].first;
      int r2 = r[p][i].second;
      int d = e[r1][r2].f;
      if (d > 0) {
        int val = flow(e[r1][r2].a, min(f, d), end);
        if (val != 0) {
          e[r1][r2].f -= val;
          return val;
        }
      }
    }
    return 0;
  }
  int solve(int start, int end) {
    int ans = 0;
    while (1) {
      rep(i, N) visit[i] = 0;
      int val = flow(start, INF, end);
      if (val == 0)
        break;
      ans += val;
    }
    return ans;
  }
};

const int S = 1111111;
int sosu[S];
vector<int> prime;
int sosuInit() {
  sosu[0] = sosu[1] = 1;
  rep(i, S) {
    if (sosu[i] == 1)
      continue;
    for (int j = i * 2; j < S; j += i)
      sosu[j] = 1;
    prime.push_back(i);
  }
}

vector<int> canop[S];

int main() {
  sosuInit();

A:;

  rep(i, S) canop[i].clear();

  int n, m;
  cin >> n >> m;

  if (n == 0 && m == 0)
    return 0;

  Flow flow;

  rep(i, n) {
    int a;
    cin >> a;
    rep(j, prime.size()) {
      if (a % prime[j] == 0) {
        canop[prime[j]].push_back(i + 1);
      }
    }
    flow.addEdge(0, i + 1, 1);
  }

  rep(i, m) {
    int b;
    cin >> b;
    rep(j, prime.size()) {
      if (b % prime[j] == 0) {
        rep(k, canop[prime[j]].size()) {
          flow.addEdge(canop[prime[j]][k], i + n + 1, 1);
        }
      }
    }
    flow.addEdge(i + n + 1, n + m + 1, 1);
  }

  int ans = flow.solve(0, n + m + 1);
  printf("%d\\n", ans);

  goto A;
}
/*

4 3
2 6 6 15
2 3 5
0 0

*/