Problem p01493 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

typedef int Weight;
struct Edge {
  int from, to;
  Weight cost;
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, Weight cost) {
  g[from].push_back(Edge{from, to, cost});
}

int dp[1111][1111][2];

int solve(int even, int odd, int edge) {
  if (even + odd == 1)
    return 1;
  if (dp[even][odd][edge] >= 0)
    return dp[even][odd][edge];
  int res = 1;
  if (even >= 2)
    chmin(res, solve(even - 1, odd, 1 - edge));
  if (odd >= 2)
    chmin(res, solve(even + 1, odd - 2, edge));
  if (even >= 1 && odd >= 1)
    chmin(res, solve(even - 1, odd, 1 - edge));
  if (edge == 1)
    chmin(res, solve(even, odd, 0));
  return 1 - res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int V;
  cin >> V;
  Graph g(V);
  REP(i, V) REP(j, V) {
    char a;
    cin >> a;
    if (a == 'Y')
      add_edge(g, i, j, 0);
  }
  vector<bool> vis(V);
  int even = 0, odd = 0, edge = 0;
  REP(i, V) {
    if (vis[i])
      continue;
    vis[i] = true;
    vi v;
    v.push_back(i);
    queue<int> que;
    que.push(i);
    while (!que.empty()) {
      int t = que.front();
      que.pop();
      for (auto j : g[t]) {
        int nx = j.to;
        if (vis[nx])
          continue;
        vis[nx] = true;
        v.push_back(nx);
        que.push(nx);
      }
    }
    if (v.size() % 2)
      odd++;
    else
      even++;
    int cnt = 0;
    REP(j, v.size()) { cnt += v.size() - g[v[j]].size() - 1; }
    cnt /= 2;
    if (cnt % 2)
      edge++;
    edge %= 2;
  }
  MS(dp, -1);
  int ans = solve(even, odd, edge);
  if (ans)
    cout << "Taro" << endl;
  else
    cout << "Hanako" << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (int)(k); i < (int)(n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-12;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/

typedef int Weight;
struct Edge {
  int from, to;
  Weight cost;
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, Weight cost) {
  g[from].push_back(Edge{from, to, cost});
}

int dp[1111][1111][2];

int solve(int even, int odd, int edge) {
  if (even + odd == 1)
    return 1;
  if (dp[even][odd][edge] >= 0)
    return dp[even][odd][edge];
  int res = 1;
  if (even >= 2)
    chmin(res, solve(even - 1, odd, 1 - edge));
  if (odd >= 2)
    chmin(res, solve(even + 1, odd - 2, edge));
  if (even >= 1 && odd >= 1)
    chmin(res, solve(even - 1, odd, 1 - edge));
  if (edge == 1)
    chmin(res, solve(even, odd, 0));
  return dp[even][odd][edge] = 1 - res;
}

int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int V;
  cin >> V;
  Graph g(V);
  REP(i, V) REP(j, V) {
    char a;
    cin >> a;
    if (a == 'Y')
      add_edge(g, i, j, 0);
  }
  vector<bool> vis(V);
  int even = 0, odd = 0, edge = 0;
  REP(i, V) {
    if (vis[i])
      continue;
    vis[i] = true;
    vi v;
    v.push_back(i);
    queue<int> que;
    que.push(i);
    while (!que.empty()) {
      int t = que.front();
      que.pop();
      for (auto j : g[t]) {
        int nx = j.to;
        if (vis[nx])
          continue;
        vis[nx] = true;
        v.push_back(nx);
        que.push(nx);
      }
    }
    if (v.size() % 2)
      odd++;
    else
      even++;
    int cnt = 0;
    REP(j, v.size()) { cnt += v.size() - g[v[j]].size() - 1; }
    cnt /= 2;
    if (cnt % 2)
      edge++;
    edge %= 2;
  }
  MS(dp, -1);
  int ans = solve(even, odd, edge);
  if (ans)
    cout << "Taro" << endl;
  else
    cout << "Hanako" << endl;
  return 0;
}