Problem p02908 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define of(i, l, r) for (int i = l; i >= r; i--)
#define fe(i, u) for (int i = head[u]; i; i = e[i].next)
#define el putchar('\n')
#define ta putchar('	')
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
inline void open(const char *s) {
#ifndef ONLINE_JUDGE
  char str[20];
  sprintf(str, "%s.in", s);
  freopen(str, "r", stdin);
  //	sprintf(str,"%s.out",s);
  //	freopen(str,"w",stdout);
#endif
}
inline int rd() {
  static int x, f;
  x = 0;
  f = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return f > 0 ? x : -x;
}
const int N = 100010;
int n, a[N], b[N], t1, t2, bel1[N], bel2[N], c1[N], c2[N], vs, vt;
bool vis[N];

int head[N << 1], tot = 1;
struct edge {
  int v, f, next;
} e[N * 20];

inline void add(int u, int v, int f) {
  e[++tot] = edge{v, f, head[u]};
  head[u] = tot;
  e[++tot] = edge{u, 0, head[v]};
  head[v] = tot;
}
int d[N << 1], cur[N << 1];
inline bool bfs() {
  fo(i, 1, vt) d[i] = -1, cur[i] = 0;
  static queue<int> q;
  while (!q.empty())
    q.pop();
  q.push(vs);
  d[vs] = 0;
  cur[vs] = head[vs];
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    fe(i, u) {
      int v = e[i].v, f = e[i].f;
      if (f && !~d[v]) {
        d[v] = d[u] + 1;
        cur[v] = head[v];
        if (v == vt)
          return 1;
        q.push(v);
      }
    }
  }
  return 0;
}
int dfs(int u, int a) {
  if (!a || u == vt)
    return a;
  int ans = 0;
  fe(i, u) {
    int v = e[i].v, f = e[i].f;
    if (f && d[v] == d[u] + 1) {
      f = dfs(v, min(a, f));
      if (!f)
        continue;
      e[i].f -= f;
      e[i ^ 1].f += f;
      ans += f;
      a -= f;
      if (!a)
        break;
    }
  }
  return ans;
}

int main() {
  n = rd();
  fo(i, 1, n) a[i] = rd() + 1;
  fo(i, 1, n) b[i] = rd() + 1;
  fo(i, 1, n) if (!vis[i]) {
    if (a[i] == i)
      continue;
    ++t1;
    for (int x = i; !vis[x]; x = a[x]) {
      vis[x] = 1, bel1[x] = t1;
      if (b[x] == x)
        ++c1[t1];
    }
  }
  memset(vis, 0, N);
  fo(i, 1, n) if (!vis[i]) {
    if (b[i] == i)
      continue;
    ++t2;
    for (int x = i; !vis[x]; x = b[x]) {
      vis[x] = 1, bel2[x] = t2;
      if (a[x] == x)
        ++c2[t2];
    }
  }
  vs = t1 + t2 + 1;
  vt = vs + 1;
  fo(i, 1, t1) if (c1[i]) add(vs, i, c1[i]);
  fo(i, 1, t2) if (c2[i]) add(i + t1, vt, c2[i]);
  fo(i, 1, n) if (a[i] != i && b[i] != i) add(bel2[i] + t1, bel1[i], 1);
  fo(i, 1, n) if (a[i] != i && b[i] != i && a[i] == b[i])
      add(bel1[i], bel2[i] + t1, 1);
  int ans = n;
  fo(i, 1, n) if (a[i] == i && b[i] == i)-- ans;
  while (bfs())
    ans -= dfs(vs, 1e9);
  cout << ans;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define fo(i, l, r) for (int i = l; i <= r; i++)
#define of(i, l, r) for (int i = l; i >= r; i--)
#define fe(i, u) for (int i = head[u]; i; i = e[i].next)
#define el putchar('\n')
#define ta putchar('	')
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
inline void open(const char *s) {
#ifndef ONLINE_JUDGE
  char str[20];
  sprintf(str, "%s.in", s);
  freopen(str, "r", stdin);
  //	sprintf(str,"%s.out",s);
  //	freopen(str,"w",stdout);
#endif
}
inline int rd() {
  static int x, f;
  x = 0;
  f = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = x * 10 + ch - '0';
  return f > 0 ? x : -x;
}
const int N = 100010;
int n, a[N], b[N], t1, t2, bel1[N], bel2[N], c1[N], c2[N], vs, vt;
bool vis[N];

int head[N << 1], tot = 1;
struct edge {
  int v, f, next;
} e[N * 20];

inline void add(int u, int v, int f) {
  e[++tot] = edge{v, f, head[u]};
  head[u] = tot;
  e[++tot] = edge{u, 0, head[v]};
  head[v] = tot;
}
int d[N << 1], cur[N << 1];
inline bool bfs() {
  fo(i, 1, vt) d[i] = -1, cur[i] = 0;
  static queue<int> q;
  while (!q.empty())
    q.pop();
  q.push(vs);
  d[vs] = 0;
  cur[vs] = head[vs];
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    fe(i, u) {
      int v = e[i].v, f = e[i].f;
      if (f && !~d[v]) {
        d[v] = d[u] + 1;
        cur[v] = head[v];
        if (v == vt)
          return 1;
        q.push(v);
      }
    }
  }
  return 0;
}
int dfs(int u, int a) {
  if (!a || u == vt)
    return a;
  int ans = 0;
  for (int &i = cur[u]; i; i = e[i].next) {
    int v = e[i].v, f = e[i].f;
    if (f && d[v] == d[u] + 1) {
      f = dfs(v, min(a, f));
      if (!f)
        continue;
      e[i].f -= f;
      e[i ^ 1].f += f;
      ans += f;
      a -= f;
      if (!a)
        break;
    }
  }
  return ans;
}

int main() {
  n = rd();
  fo(i, 1, n) a[i] = rd() + 1;
  fo(i, 1, n) b[i] = rd() + 1;
  fo(i, 1, n) if (!vis[i]) {
    if (a[i] == i)
      continue;
    ++t1;
    for (int x = i; !vis[x]; x = a[x]) {
      vis[x] = 1, bel1[x] = t1;
      if (b[x] == x)
        ++c1[t1];
    }
  }
  memset(vis, 0, N);
  fo(i, 1, n) if (!vis[i]) {
    if (b[i] == i)
      continue;
    ++t2;
    for (int x = i; !vis[x]; x = b[x]) {
      vis[x] = 1, bel2[x] = t2;
      if (a[x] == x)
        ++c2[t2];
    }
  }
  vs = t1 + t2 + 1;
  vt = vs + 1;
  fo(i, 1, t1) if (c1[i]) add(vs, i, c1[i]);
  fo(i, 1, t2) if (c2[i]) add(i + t1, vt, c2[i]);
  fo(i, 1, n) if (a[i] != i && b[i] != i) add(bel2[i] + t1, bel1[i], 1);
  fo(i, 1, n) if (a[i] != i && b[i] != i && a[i] == b[i])
      add(bel1[i], bel2[i] + t1, 1);
  int ans = n;
  fo(i, 1, n) if (a[i] == i && b[i] == i)-- ans;
  while (bfs())
    ans -= dfs(vs, 1e9);
  cout << ans;
  return 0;
}