Problem p02908 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
namespace mine {
typedef long long ll;
#define pr pair<int, int>
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll << (x))
#define GG(x)                                                                  \
  if (x)                                                                       \
  puts("error")
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
ll qread() {
  ll ans = 0, f = 1;
  char c = getchar();
  while (c < '0' or c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while ('0' <= c and c <= '9')
    ans = ans * 10 + c - '0', c = getchar();
  return ans * f;
}
void write(ll num) {
  if (num < 0)
    putchar('-'), num = -num;
  if (num >= 10)
    write(num / 10);
  putchar('0' + num % 10);
}
void write1(ll num) {
  write(num);
  putchar(' ');
}
void write2(ll num) {
  write(num);
  putchar('\n');
}
template <typename T> void chmax(T &x, const T y) { x = (x > y ? x : y); }
template <typename T> void chmin(T &x, const T y) { x = (x < y ? x : y); }
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
inline int mm(const int x) { return x >= MOD ? x - MOD : x; }
template <typename T> inline void add(T &x, const T y) { x = mm(x + y); }
inline ll qpower(ll x, ll e) {
  ll ans = 1;
  GG(e < 0);
  while (e) {
    if (e & 1)
      ans = ans * x % MOD;
    x = x * x % MOD;
    e >>= 1;
  }
  return ans;
}
ll invm(ll x) { return qpower(x, MOD - 2); }
const int N = 1e6 + 10;

namespace MM {
int hou[N];
struct Edge {
  int y, c, g;
} e[N];
int ln = 0;
int oth(int x) { return x & 1 ? x + 1 : x - 1; }
void insert(int x, int y, int c) {
  e[++ln] = (Edge){y, c, hou[x]};
  hou[x] = ln;
  e[++ln] = (Edge){x, 0, hou[y]};
  hou[y] = ln;
}
int st, ed;
int h[N];
queue<int> qq;
int cur[N];
bool bfs() {
  for (int i = st; i <= ed; i++)
    h[i] = 0, cur[i] = hou[i];
  qq.push(st);
  h[st] = 1;
  while (qq.size()) {
    int x = qq.front();
    qq.pop();
    for (int k = hou[x]; k > 0; k = e[k].g) {
      int y = e[k].y;
      if (e[k].c and !h[y])
        h[y] = h[x] + 1, qq.push(y);
    }
  }
  return h[ed] > 0;
}
int dfs(int x, int flow) {
  if (x == ed)
    return flow;
  int tt = 0;
  for (int k = cur[x]; k > 0; k = e[k].g) {
    int y = e[k].y;
    if (h[y] == h[x] + 1 and e[k].c and tt < flow) {
      int out = dfs(y, min(flow - tt, e[k].c));
      e[k].c -= out;
      e[oth(k)].c += out;
      tt += out;
    }
    if (tt == flow)
      break;

    if (e[k].c == 0 and cur[x] == k)
      cur[x] = e[k].g;
  }
  if (!tt)
    h[x] = 0;
  return tt;
}
int solve() {
  int ans = 0;
  while (bfs())
    ans += dfs(st, INF);
  return ans;
}
}; // namespace MM
struct DSU {
  int fa[N];
  DSU() {
    for (int i = 0; i < N; i++)
      fa[i] = i;
  }
  int findfa(int x) { return x == fa[x] ? x : fa[x] = findfa(fa[x]); }
  void merg(int x, int y) {
    x = findfa(x), y = findfa(y);
    fa[x] = y;
  }
} dsu[2];
int p[N], q[N];
void main() {
  int n = qread();
  for (int i = 1; i <= n; i++)
    p[i] = qread() + 1, dsu[0].merg(i, p[i]);
  for (int i = 1; i <= n; i++)
    q[i] = qread() + 1, dsu[1].merg(i, q[i]);
  using namespace MM;
  st = 0, ed = n + n + 1;
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    cnt += (p[i] != q[i]);
    int fx = dsu[0].findfa(p[i]), fy = n + dsu[1].findfa(q[i]);
    if (p[i] == i and q[i] != i)
      insert(st, fy, 1);
    if (p[i] != i and q[i] == i)
      insert(fx, ed, 1);
    if (p[i] == q[i] and p[i] != i)
      insert(fx, fy, 1), insert(fy, fx, 1), cnt++;
    if (p[i] != q[i] and p[i] != i and q[i] != i)
      insert(fx, fy, 1);
  }
  write(cnt - solve());
}
}; // namespace mine
int main() {
  srand(time(0));
  mine::main();
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
namespace mine {
typedef long long ll;
#define pr pair<int, int>
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll << (x))
#define GG(x)                                                                  \
  if (x)                                                                       \
  puts("error")
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
ll qread() {
  ll ans = 0, f = 1;
  char c = getchar();
  while (c < '0' or c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while ('0' <= c and c <= '9')
    ans = ans * 10 + c - '0', c = getchar();
  return ans * f;
}
void write(ll num) {
  if (num < 0)
    putchar('-'), num = -num;
  if (num >= 10)
    write(num / 10);
  putchar('0' + num % 10);
}
void write1(ll num) {
  write(num);
  putchar(' ');
}
void write2(ll num) {
  write(num);
  putchar('\n');
}
template <typename T> void chmax(T &x, const T y) { x = (x > y ? x : y); }
template <typename T> void chmin(T &x, const T y) { x = (x < y ? x : y); }
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }

const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
inline int mm(const int x) { return x >= MOD ? x - MOD : x; }
template <typename T> inline void add(T &x, const T y) { x = mm(x + y); }
inline ll qpower(ll x, ll e) {
  ll ans = 1;
  GG(e < 0);
  while (e) {
    if (e & 1)
      ans = ans * x % MOD;
    x = x * x % MOD;
    e >>= 1;
  }
  return ans;
}
ll invm(ll x) { return qpower(x, MOD - 2); }
const int N = 1e6 + 10;

namespace MM {
int hou[N];
struct Edge {
  int y, c, g;
} e[N];
int ln = 0;
int oth(int x) { return x & 1 ? x + 1 : x - 1; }
void insert(int x, int y, int c) {
  e[++ln] = (Edge){y, c, hou[x]};
  hou[x] = ln;
  e[++ln] = (Edge){x, 0, hou[y]};
  hou[y] = ln;
}
int st, ed;
int h[N];
queue<int> qq;
int cur[N];
bool bfs() {
  for (int i = st; i <= ed; i++)
    h[i] = 0, cur[i] = hou[i];
  qq.push(st);
  h[st] = 1;
  while (qq.size()) {
    int x = qq.front();
    qq.pop();
    for (int k = hou[x]; k > 0; k = e[k].g) {
      int y = e[k].y;
      if (e[k].c and !h[y])
        h[y] = h[x] + 1, qq.push(y);
    }
  }
  return h[ed] > 0;
}
int dfs(int x, int flow) {
  if (x == ed)
    return flow;
  int tt = 0;
  for (int k = cur[x]; k > 0; k = e[k].g) {
    int y = e[k].y;
    if (h[y] == h[x] + 1 and e[k].c and tt < flow) {
      int out = dfs(y, min(flow - tt, e[k].c));
      e[k].c -= out;
      e[oth(k)].c += out;
      tt += out;
    }
    if (tt == flow)
      break;

    if (e[k].c == 0)
      cur[x] = e[k].g;
  }
  if (!tt)
    h[x] = 0;
  return tt;
}
int solve() {
  int ans = 0;
  while (bfs())
    ans += dfs(st, INF);
  return ans;
}
}; // namespace MM
struct DSU {
  int fa[N];
  DSU() {
    for (int i = 0; i < N; i++)
      fa[i] = i;
  }
  int findfa(int x) { return x == fa[x] ? x : fa[x] = findfa(fa[x]); }
  void merg(int x, int y) {
    x = findfa(x), y = findfa(y);
    fa[x] = y;
  }
} dsu[2];
int p[N], q[N];
void main() {
  int n = qread();
  for (int i = 1; i <= n; i++)
    p[i] = qread() + 1, dsu[0].merg(i, p[i]);
  for (int i = 1; i <= n; i++)
    q[i] = qread() + 1, dsu[1].merg(i, q[i]);
  using namespace MM;
  st = 0, ed = n + n + 1;
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    cnt += (p[i] != q[i]);
    int fx = dsu[0].findfa(p[i]), fy = n + dsu[1].findfa(q[i]);
    if (p[i] == i and q[i] != i)
      insert(st, fy, 1);
    if (p[i] != i and q[i] == i)
      insert(fx, ed, 1);
    if (p[i] == q[i] and p[i] != i)
      insert(fx, fy, 1), insert(fy, fx, 1), cnt++;
    if (p[i] != q[i] and p[i] != i and q[i] != i)
      insert(fx, fy, 1);
  }
  write(cnt - solve());
}
}; // namespace mine
int main() {
  srand(time(0));
  mine::main();
}