Problem p01493 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define MAX_N 1000
#define INF 100000000
#define MOD 1000000007
#define RANK 1000000000
#define EPS 1e-10
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> IP;

struct UF {
  int par[MAX_N];
  int rank[MAX_N];
  int si[MAX_N];

  void init(int n) {
    rep(i, n) {
      par[i] = i;
      rank[i] = 0;
      si[i] = 1;
    }
  }

  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
      si[y] += si[x];
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
      si[x] += si[y];
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
} uf;

int n, N;
int cnte = 0;
int dp[1001][1001][2]; // 1,2

int dfs(int ki, int gu, int res) {
  if (dp[ki][gu][res] != -1)
    return dp[ki][gu][res];
  int ret = 0;
  int rec;
  if (ki >= 2) {
    rec = dfs(ki - 2, gu + 1, res);
    if (rec == 0) {
      dp[ki][gu][res] = 1;
      return 1;
    }
  }
  if (gu >= 1) {
    rec = dfs(ki, gu - 1, res ^ 1);
    if (rec == 0) {
      dp[ki][gu][res] = 1;
      return 1;
    }
  }
  if (gu >= 1) {
    rec = dfs(ki, gu - 1, res ^ 1);
    if (rec == 0) {
      dp[ki][gu][res] = 1;
      return 1;
    }
  }
  if (res == 1) {
    rec = dfs(ki, gu, res - 1);
    if (rec == 0) {
      dp[ki][gu][res] = 1;
      return 1;
    }
  }
  dp[ki][gu][res] = 0;
  return 0;
}

int main() {
  cin >> n;
  memset(dp, -1, sizeof(dp));
  uf.init(n);
  rep(i, n) rep(j, n) {
    char tmp;
    cin >> tmp;
    if (i == j)
      continue;
    if (tmp == 'Y') {
      uf.unite(i, j);
      cnte++;
    }
  }
  cnte /= 2;
  N = n * (n - 1) / 2;
  if (n % 2) {
    if ((N - cnte) % 2 == 0) {
      cout << "Hanako" << endl;
    } else {
      cout << "Taro" << endl;
    }
    return 0;
  }
  int ki = 0;
  int sub = 0;
  int sum = 0;
  rep(i, n) {
    if (uf.find(i) != i)
      continue;
    sub++;
    sum += (uf.si[i] - 1) * uf.si[i] / 2;
    if (uf.si[i] % 2 == 1) {
      ki++;
    }
  }
  dp[2][0][0] = 0;
  dp[2][0][1] = 1;
  dp[0][2][0] = 0;
  dp[0][2][1] = 1;
  dp[1][1][0] = 0;
  dp[1][1][1] = 1;
  int ans = dfs(ki, sub - ki, (sum - cnte) % 2);
  if (ans % 2) {
    cout << "Taro" << endl;
  } else {
    cout << "Hanako" << endl;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define MAX_N 1000
#define INF 100000000
#define MOD 1000000007
#define RANK 1000000000
#define EPS 1e-10
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> IP;

struct UF {
  int par[MAX_N];
  int rank[MAX_N];
  int si[MAX_N];

  void init(int n) {
    rep(i, n) {
      par[i] = i;
      rank[i] = 0;
      si[i] = 1;
    }
  }

  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
      si[y] += si[x];
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
      si[x] += si[y];
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
} uf;

int n, N;
int cnte = 0;
int dp[1001][1001][2]; // 1,2

int dfs(int ki, int gu, int res) {
  if (dp[ki][gu][res] != -1)
    return dp[ki][gu][res];
  int ret = 0;
  int rec;
  rec = dfs(ki - 2, gu + 1, res);
  if (rec == 0) {
    dp[ki][gu][res] = 1;
    return 1;
  }
  rec = dfs(ki, gu - 1, res ^ 1);
  if (rec == 0) {
    dp[ki][gu][res] = 1;
    return 1;
  }
  rec = dfs(ki, gu - 1, res ^ 1);
  if (rec == 0) {
    dp[ki][gu][res] = 1;
    return 1;
  }
  if (res == 1) {
    rec = dfs(ki, gu, res - 1);
    if (rec == 0) {
      dp[ki][gu][res] = 1;
      return 1;
    }
  }
  dp[ki][gu][res] = 0;
  return 0;
}

int main() {
  cin >> n;
  memset(dp, -1, sizeof(dp));
  uf.init(n);
  rep(i, n) rep(j, n) {
    char tmp;
    cin >> tmp;
    if (i == j)
      continue;
    if (tmp == 'Y') {
      uf.unite(i, j);
      cnte++;
    }
  }
  cnte /= 2;
  N = n * (n - 1) / 2;
  if (n % 2) {
    if ((N - cnte) % 2 == 0) {
      cout << "Hanako" << endl;
    } else {
      cout << "Taro" << endl;
    }
    return 0;
  }
  int ki = 0;
  int sub = 0;
  int sum = 0;
  rep(i, n) {
    if (uf.find(i) != i)
      continue;
    sub++;
    sum += (uf.si[i] - 1) * uf.si[i] / 2;
    if (uf.si[i] % 2 == 1) {
      ki++;
    }
  }
  dp[2][0][0] = 0;
  dp[2][0][1] = 1;
  dp[0][2][0] = 0;
  dp[0][2][1] = 1;
  dp[1][1][0] = 0;
  dp[1][1][1] = 1;
  int ans = dfs(ki, sub - ki, (sum - cnte) % 2);
  if (ans % 2) {
    cout << "Taro" << endl;
  } else {
    cout << "Hanako" << endl;
  }
}