Problem p02908 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define For(i, x, y) for (register int i = (x); i <= (y); i++)
#define FOR(i, x, y) for (register int i = (x); i < (y); i++)
#define Dow(i, x, y) for (register int i = (x); i >= (y); i--)
#define Debug(v)                                                               \
  for (auto i : v)                                                             \
    printf("%lld ", i);                                                        \
  puts("")
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define ep emplace_back
#define siz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define fil(a, b) memset((a), (b), sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pa;
typedef pair<ll, ll> PA;
typedef vector<int> poly;
inline ll read() {
  ll x = 0, f = 1;
  char c = getchar();
  while ((c < '0' || c > '9') && (c != '-'))
    c = getchar();
  if (c == '-')
    f = -1, c = getchar();
  while (c >= '0' && c <= '9')
    x = x * 10 + c - '0', c = getchar();
  return x * f;
}

const int N = 5e5 + 10;
int n, S, T, a[N], b[N], cnt, id[2][N];
poly v1[N], v2[N];
map<int, int> f, g;

namespace Flow {
int n, tot = -1, first[N], to[N << 1], flow[N << 1], last[N << 1];
inline void add(int x, int y, int z) {
  to[++tot] = y, flow[tot] = z, last[tot] = first[x], first[x] = tot;
}
inline void Add(int x, int y, int z) { add(x, y, z), add(y, x, 0); }
int hd, tl, q[N], deep[N];
inline bool bfs(int s, int t) {
  For(i, 1, n) deep[i] = 0;
  hd = 0, q[tl = 1] = s, deep[s] = 1;
  while (hd < tl) {
    int u = q[++hd];
    for (int i = first[u]; i != -1; i = last[i])
      if (!deep[to[i]] && flow[i])
        deep[q[++tl] = to[i]] = deep[u] + 1;
  }
  return deep[t];
}
int cur[N];
inline void init() { For(i, 1, n) cur[i] = first[i]; }
inline int dfs(int u, int t, int dist) {
  if (u == t || !dist)
    return dist;
  int Flow = 0, f;
  for (int i = cur[u]; i != -1; i = last[i]) {
    cur[u] = i;
    if (deep[to[i]] == deep[u] + 1 && (f = dfs(to[i], t, min(dist, flow[i])))) {
      dist -= f, Flow += f, flow[i] -= f, flow[i ^ 1] += f;
      if (!dist)
        break;
    }
  }
  return Flow;
}
const int inf = 1e9;
inline int Dinic(int s, int t) {
  int ans = 0;
  while (bfs(s, t))
    init(), ans += dfs(s, t, inf);
  return ans;
}
} // namespace Flow

int main() {
  n = read();
  For(i, 1, n) a[i] = read() + 1;
  For(i, 1, n) b[i] = read() + 1;
  int ans = n;
  For(i, 1, n) if (a[i] == b[i] && a[i] == i)-- ans, id[i][0] = id[i][1] = -1;
  fil(Flow::first, -1), S = 1, T = 2, cnt = 2;
  For(i, 1, n) if (!id[0][i]) {
    ++cnt;
    int tot = 0;
    for (int j = i; !id[0][j]; j = a[j]) {
      id[0][j] = cnt;
      if (b[j] == j)
        ++tot;
      v1[cnt].pb(j);
    }
    Flow::Add(S, cnt, tot);
    Flow::Add(cnt, T, 0);
  }
  int cnt1 = cnt;
  For(i, 1, n) if (!id[1][i]) {
    ++cnt;
    int tot = 0;
    for (int j = i; !id[1][j]; j = b[j]) {
      id[1][j] = cnt;
      if (a[j] == j)
        ++tot;
      v2[cnt].pb(j);
    }
    Flow::Add(cnt, T, tot);
    Flow::Add(S, cnt, 0);
  }
  Flow::n = cnt;
  For(i, 1, cnt1) {
    f.clear(), g.clear();
    for (auto j : v1[i]) {
      if (a[j] == b[j])
        f[id[1][j]]++;
      g[id[1][j]]++;
    }
    for (auto j : f)
      Flow::Add(i, j.fi, j.se);
    for (auto j : g)
      Flow::Add(j.fi, i, j.se);
  }
  printf("%d\n", ans - Flow::Dinic(S, T));
}

Fixed submission:
#include <bits/stdc++.h>
#define For(i, x, y) for (register int i = (x); i <= (y); i++)
#define FOR(i, x, y) for (register int i = (x); i < (y); i++)
#define Dow(i, x, y) for (register int i = (x); i >= (y); i--)
#define Debug(v)                                                               \
  for (auto i : v)                                                             \
    printf("%lld ", i);                                                        \
  puts("")
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define ep emplace_back
#define siz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define fil(a, b) memset((a), (b), sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pa;
typedef pair<ll, ll> PA;
typedef vector<int> poly;
inline ll read() {
  ll x = 0, f = 1;
  char c = getchar();
  while ((c < '0' || c > '9') && (c != '-'))
    c = getchar();
  if (c == '-')
    f = -1, c = getchar();
  while (c >= '0' && c <= '9')
    x = x * 10 + c - '0', c = getchar();
  return x * f;
}

const int N = 5e5 + 10;
int n, S, T, a[N], b[N], cnt, id[2][N];
poly v1[N], v2[N];
map<int, int> f, g;

namespace Flow {
int n, tot = -1, first[N], to[N << 1], flow[N << 1], last[N << 1];
inline void add(int x, int y, int z) {
  to[++tot] = y, flow[tot] = z, last[tot] = first[x], first[x] = tot;
}
inline void Add(int x, int y, int z) { add(x, y, z), add(y, x, 0); }
int hd, tl, q[N], deep[N];
inline bool bfs(int s, int t) {
  For(i, 1, n) deep[i] = 0;
  hd = 0, q[tl = 1] = s, deep[s] = 1;
  while (hd < tl) {
    int u = q[++hd];
    for (int i = first[u]; i != -1; i = last[i])
      if (!deep[to[i]] && flow[i])
        deep[q[++tl] = to[i]] = deep[u] + 1;
  }
  return deep[t];
}
int cur[N];
inline void init() { For(i, 1, n) cur[i] = first[i]; }
inline int dfs(int u, int t, int dist) {
  if (u == t || !dist)
    return dist;
  int Flow = 0, f;
  for (int i = cur[u]; i != -1; i = last[i]) {
    cur[u] = i;
    if (deep[to[i]] == deep[u] + 1 && (f = dfs(to[i], t, min(dist, flow[i])))) {
      dist -= f, Flow += f, flow[i] -= f, flow[i ^ 1] += f;
      if (!dist)
        break;
    }
  }
  return Flow;
}
const int inf = 1e9;
inline int Dinic(int s, int t) {
  int ans = 0;
  while (bfs(s, t))
    init(), ans += dfs(s, t, inf);
  return ans;
}
} // namespace Flow

int main() {
  n = read();
  For(i, 1, n) a[i] = read() + 1;
  For(i, 1, n) b[i] = read() + 1;
  int ans = n;
  For(i, 1, n) {
    if (a[i] == b[i] && a[i] == i)
      --ans, id[0][i] = id[1][i] = -1;
  }
  fil(Flow::first, -1), S = 1, T = 2, cnt = 2;
  For(i, 1, n) if (!id[0][i]) {
    ++cnt;
    int tot = 0;
    for (int j = i; !id[0][j]; j = a[j]) {
      id[0][j] = cnt;
      if (b[j] == j)
        ++tot;
      v1[cnt].pb(j);
    }
    Flow::Add(S, cnt, tot);
    Flow::Add(cnt, T, 0);
  }
  int cnt1 = cnt;
  For(i, 1, n) if (!id[1][i]) {
    ++cnt;
    int tot = 0;
    for (int j = i; !id[1][j]; j = b[j]) {
      id[1][j] = cnt;
      if (a[j] == j)
        ++tot;
      v2[cnt].pb(j);
    }
    Flow::Add(cnt, T, tot);
    Flow::Add(S, cnt, 0);
  }
  Flow::n = cnt;
  For(i, 1, cnt1) {
    f.clear(), g.clear();
    for (auto j : v1[i]) {
      if (a[j] == b[j])
        f[id[1][j]]++;
      g[id[1][j]]++;
    }
    for (auto j : f)
      Flow::Add(i, j.fi, j.se);
    for (auto j : g)
      Flow::Add(j.fi, i, j.se);
  }
  printf("%d\n", ans - Flow::Dinic(S, T));
}