Problem p02908 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define clr(x) memset(x, 0, sizeof x)
#define For(i, a, b) for (int i = (a); i <= (b); i++)
#define Fod(i, b, a) for (int i = (b); i >= (a); i--)
#define pb(x) push_back(x)
#define mp(x, y) make_pair(x, y)
#define fi first
#define se second
#define outval(x) cerr << #x " = " << x << endl
#define outtag(x) cerr << "-----------------" #x "-----------------\n"
#define outarr(a, L, R)                                                        \
  cerr << #a "[" << L << ".." << R << "] = ";                                  \
  For(_x, L, R) cerr << a[_x] << " ";                                          \
  cerr << endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
LL read() {
  LL x = 0, f = 0;
  char ch = getchar();
  while (!isdigit(ch))
    f = ch == '-', ch = getchar();
  while (isdigit(ch))
    x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
  return f ? -x : x;
}
const int N = 100005, INF = 1e9;
namespace flows {
const int N = 100005 * 2, M = N * 2;
struct Edge {
  int x, y, nxt, cap;
  Edge() {}
  Edge(int _x, int _y, int _nxt, int _cap) {
    x = _x, y = _y, nxt = _nxt, cap = _cap;
  }
} e[M];
int n, S, T, cnt;
int fst[N], cur[N], dis[N];
void clear(int _n, int _S, int _T) {
  n = _n, S = _S, T = _T, cnt = 1;
  clr(fst);
}
void Add(int x, int y, int cap) {
  e[++cnt] = Edge(x, y, fst[x], cap), fst[x] = cnt;
  e[++cnt] = Edge(y, x, fst[y], 0), fst[y] = cnt;
}
int bfs() {
  static queue<int> q;
  For(i, 1, n) dis[i] = 0;
  dis[S] = 1;
  q.push(S);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = fst[x]; i; i = e[i].nxt) {
      int y = e[i].y;
      if (e[i].cap && !dis[y]) {
        dis[y] = dis[x] + 1;
        q.push(y);
      }
    }
  }
  return dis[T] != 0;
}
int dfs(int x, int Lim) {
  if (x == T || !Lim)
    return Lim;
  int rem = Lim;
  for (int &i = cur[x]; i; i = e[i].nxt) {
    int y = e[i].y;
    if (dis[x] + 1 == dis[y] && e[i].cap) {
      int d = dfs(y, min(rem, e[i].cap));
      rem -= d, e[i].cap -= d, e[i ^ 1].cap += d;
    }
  }
  return Lim - rem;
}
int Dinic() {
  int res = 0;
  while (bfs()) {
    For(i, 1, n) cur[i] = fst[i];
    res += dfs(S, INF);
  }
  return res;
}
} // namespace flows
int n, c = 0;
int p[N], q[N];
int x[N], y[N];
int main() {
  n = read();
  For(i, 1, n) p[i] = read() + 1;
  For(i, 1, n) q[i] = read() + 1;
  For(i, 1, n) {
    if (x[i])
      continue;
    c++;
    for (int j = i; !x[j]; j = p[j])
      x[j] = c;
  }
  For(i, 1, n) {
    if (y[i])
      continue;
    c++;
    for (int j = i; !y[j]; j = q[j])
      y[j] = c;
  }
  int S = c + 1, T = S + 1;
  flows::clear(T, S, T);
  int ans = 0;
  For(i, 1, n) {
    if (i == p[i] && i == q[i])
      ans++;
    else if (i == p[i] && i != q[i])
      flows::Add(S, y[i], 1);
    else if (i == q[i] && i != p[i])
      flows::Add(x[i], T, 1);
    else if (p[i] != q[i])
      flows::Add(x[i], y[i], 1);
    else {
      flows::Add(x[i], y[i], 1);
      flows::Add(y[i], x[i], 1);
    }
  }
  ans += flows::Dinic();
  cout << n - ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define clr(x) memset(x, 0, sizeof x)
#define For(i, a, b) for (int i = (a); i <= (b); i++)
#define Fod(i, b, a) for (int i = (b); i >= (a); i--)
#define pb(x) push_back(x)
#define mp(x, y) make_pair(x, y)
#define fi first
#define se second
#define outval(x) cerr << #x " = " << x << endl
#define outtag(x) cerr << "-----------------" #x "-----------------\n"
#define outarr(a, L, R)                                                        \
  cerr << #a "[" << L << ".." << R << "] = ";                                  \
  For(_x, L, R) cerr << a[_x] << " ";                                          \
  cerr << endl;
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;
LL read() {
  LL x = 0, f = 0;
  char ch = getchar();
  while (!isdigit(ch))
    f = ch == '-', ch = getchar();
  while (isdigit(ch))
    x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
  return f ? -x : x;
}
const int N = 100005, INF = 1e9;
namespace flows {
const int N = 100005 * 2, M = N * 2;
struct Edge {
  int x, y, nxt, cap;
  Edge() {}
  Edge(int _x, int _y, int _nxt, int _cap) {
    x = _x, y = _y, nxt = _nxt, cap = _cap;
  }
} e[M];
int n, S, T, cnt;
int fst[N], cur[N], dis[N];
void clear(int _n, int _S, int _T) {
  n = _n, S = _S, T = _T, cnt = 1;
  clr(fst);
}
void Add(int x, int y, int cap) {
  e[++cnt] = Edge(x, y, fst[x], cap), fst[x] = cnt;
  e[++cnt] = Edge(y, x, fst[y], 0), fst[y] = cnt;
}
int bfs() {
  static queue<int> q;
  For(i, 1, n) dis[i] = 0;
  dis[S] = 1;
  q.push(S);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = fst[x]; i; i = e[i].nxt) {
      int y = e[i].y;
      if (e[i].cap && !dis[y]) {
        dis[y] = dis[x] + 1;
        q.push(y);
      }
    }
  }
  return dis[T] != 0;
}
int dfs(int x, int Lim) {
  if (x == T || !Lim)
    return Lim;
  int rem = Lim;
  for (int &i = cur[x]; i; i = e[i].nxt) {
    int y = e[i].y;
    if (dis[x] + 1 == dis[y] && e[i].cap) {
      int d = dfs(y, min(rem, e[i].cap));
      rem -= d, e[i].cap -= d, e[i ^ 1].cap += d;
      if (!rem)
        break;
    }
  }
  return Lim - rem;
}
int Dinic() {
  int res = 0;
  while (bfs()) {
    For(i, 1, n) cur[i] = fst[i];
    res += dfs(S, INF);
  }
  return res;
}
} // namespace flows
int n, c = 0;
int p[N], q[N];
int x[N], y[N];
int main() {
  n = read();
  For(i, 1, n) p[i] = read() + 1;
  For(i, 1, n) q[i] = read() + 1;
  For(i, 1, n) {
    if (x[i])
      continue;
    c++;
    for (int j = i; !x[j]; j = p[j])
      x[j] = c;
  }
  For(i, 1, n) {
    if (y[i])
      continue;
    c++;
    for (int j = i; !y[j]; j = q[j])
      y[j] = c;
  }
  int S = c + 1, T = S + 1;
  flows::clear(T, S, T);
  int ans = 0;
  For(i, 1, n) {
    if (i == p[i] && i == q[i])
      ans++;
    else if (i == p[i] && i != q[i])
      flows::Add(S, y[i], 1);
    else if (i == q[i] && i != p[i])
      flows::Add(x[i], T, 1);
    else if (p[i] != q[i])
      flows::Add(x[i], y[i], 1);
    else {
      flows::Add(x[i], y[i], 1);
      flows::Add(y[i], x[i], 1);
    }
  }
  ans += flows::Dinic();
  cout << n - ans << endl;
  return 0;
}