Problem p02908 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define rep(i, n) for (rint i = 1; i <= (n); i++)
#define re0(i, n) for (rint i = 0; i < (int)n; i++)
#define travel(i, u) for (rint i = head[u]; i; i = e[i].nxt)
#define rint register int
using namespace std;

typedef long long lo;

template <typename tp> inline void read(tp &x) {
  x = 0;
  char c = getchar();
  int f = 0;
  for (; c < '0' || c > '9'; f |= c == '-', c = getchar())
    ;
  for (; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar())
    ;
  if (f)
    x = -x;
}
namespace mf {
static const int N = 5e5 + 233;
static const int M = 2e6 + 233;
static const int inf = 1e8;
struct E {
  int nxt, to, fl;
} e[M << 1];
int d[N], head[N], cur[N], e_cnt = 1;
int n, s, t;
inline void init(int _n, int _s, int _t) {
  n = _n;
  s = _s;
  t = _t;
  fill(head, head + n + 1, 0);
  e_cnt = 1;
}
inline void add(int u, int v, int fl) {
  e[++e_cnt] = (E){head[u], v, fl};
  head[u] = e_cnt;
}
inline void link(int u, int v, int fl) {
  add(u, v, fl);
  add(v, u, 0);
}
inline bool bfs(void) {
  queue<int> q;
  fill(d, d + n + 1, -1);
  d[s] = 0;
  q.push(s);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = head[u]; i; i = e[i].nxt)
      if (e[i].fl) {
        int v = e[i].to;
        if (!~d[v])
          d[v] = d[u] + 1, q.push(v);
      }
  }
  return d[t] != -1;
}
inline int dfs(int u, int f) {
  if (u == t || !f)
    return f;
  int used = 0, t;
  for (int i = head[u]; i; i = e[i].nxt)
    if (e[i].fl) {
      int v = e[i].to;
      if (d[v] != d[u] + 1)
        continue;
      t = dfs(v, min(f - used, e[i].fl));
      used += t;
      e[i].fl -= t;
      e[i ^ 1].fl += t;
      if (used == f)
        break;
    }
  if (!used)
    d[u] = -1;
  return used;
}
inline int doit(void) {
  int fl = 0;
  while (bfs()) {
    memcpy(cur, head, sizeof(int) * (n + 2));
    fl += dfs(s, inf);
  }
  return fl;
}
} // namespace mf
const int N = 5e5 + 233;
int n, cnt, a[N], b[N], p[N], q[N], x[N][2], y[N][2], vis[N];
inline void doit(int p[], int a[]) {
  memset(vis, 0, sizeof vis);
  rep(i, n) if (!vis[i]) {
    ++cnt;
    for (int u = i; !vis[u]; u = p[u])
      a[u] = cnt, vis[u] = true;
  }
}

using mf::link;

int main(void) {
  read(n);
  rep(i, n) read(p[i]), ++p[i];
  rep(i, n) read(q[i]), ++q[i];
  doit(p, a);
  doit(q, b);
  int S = cnt + 1, T = S + 1;
  mf::init(T, S, T);
  int ans = 0;
  rep(i, n) {
    if (p[i] == q[i]) {
      if (q[i] == i)
        ++ans;
      else {
        link(a[i], b[i], 1);
        link(b[i], a[i], 1);
      }
    } else {
      if (q[i] == i)
        link(a[i], T, 1);
      else if (p[i] == i)
        link(S, b[i], 1);
      else
        link(a[i], b[i], 1);
    }
  }
  ans += mf::doit();
  cout << n - ans << "\n";
}


Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (rint i = 1; i <= (n); i++)
#define re0(i, n) for (rint i = 0; i < (int)n; i++)
#define travel(i, u) for (rint i = head[u]; i; i = e[i].nxt)
#define rint register int
using namespace std;

typedef long long lo;

template <typename tp> inline void read(tp &x) {
  x = 0;
  char c = getchar();
  int f = 0;
  for (; c < '0' || c > '9'; f |= c == '-', c = getchar())
    ;
  for (; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar())
    ;
  if (f)
    x = -x;
}
namespace mf {
static const int N = 5e5 + 233;
static const int M = 2e6 + 233;
static const int inf = 1e8;
struct E {
  int nxt, to, fl;
} e[M << 1];
int d[N], head[N], cur[N], e_cnt = 1;
int n, s, t;
inline void init(int _n, int _s, int _t) {
  n = _n;
  s = _s;
  t = _t;
  fill(head, head + n + 1, 0);
  e_cnt = 1;
}
inline void add(int u, int v, int fl) {
  e[++e_cnt] = (E){head[u], v, fl};
  head[u] = e_cnt;
}
inline void link(int u, int v, int fl) {
  add(u, v, fl);
  add(v, u, 0);
}
inline bool bfs(void) {
  queue<int> q;
  fill(d, d + n + 1, -1);
  d[s] = 0;
  q.push(s);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = head[u]; i; i = e[i].nxt)
      if (e[i].fl) {
        int v = e[i].to;
        if (!~d[v])
          d[v] = d[u] + 1, q.push(v);
      }
  }
  return d[t] != -1;
}
inline int dfs(int u, int f) {
  if (u == t || !f)
    return f;
  int used = 0, t;
  for (int &i = cur[u]; i; i = e[i].nxt)
    if (e[i].fl) {
      int v = e[i].to;
      if (d[v] != d[u] + 1)
        continue;
      t = dfs(v, min(f - used, e[i].fl));
      used += t;
      e[i].fl -= t;
      e[i ^ 1].fl += t;
      if (used == f)
        break;
    }
  if (!used)
    d[u] = -1;
  return used;
}
inline int doit(void) {
  int fl = 0;
  while (bfs()) {
    memcpy(cur, head, sizeof(int) * (n + 2));
    fl += dfs(s, inf);
  }
  return fl;
}
} // namespace mf
const int N = 5e5 + 233;
int n, cnt, a[N], b[N], p[N], q[N], x[N][2], y[N][2], vis[N];
inline void doit(int p[], int a[]) {
  memset(vis, 0, sizeof vis);
  rep(i, n) if (!vis[i]) {
    ++cnt;
    for (int u = i; !vis[u]; u = p[u])
      a[u] = cnt, vis[u] = true;
  }
}

using mf::link;

int main(void) {
  read(n);
  rep(i, n) read(p[i]), ++p[i];
  rep(i, n) read(q[i]), ++q[i];
  doit(p, a);
  doit(q, b);
  int S = cnt + 1, T = S + 1;
  mf::init(T, S, T);
  int ans = 0;
  rep(i, n) {
    if (p[i] == q[i]) {
      if (q[i] == i)
        ++ans;
      else {
        link(a[i], b[i], 1);
        link(b[i], a[i], 1);
      }
    } else {
      if (q[i] == i)
        link(a[i], T, 1);
      else if (p[i] == i)
        link(S, b[i], 1);
      else
        link(a[i], b[i], 1);
    }
  }
  ans += mf::doit();
  cout << n - ans << "\n";
}