Problem p03668 (C++)

Buggy submission (status: Runtime Error):
// Template {{{
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;

#ifdef LOCAL
#include "contest.h"
#else
#define error(args...)
#endif

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
inline bool valid(int x, int w) { return 0 <= x && x < w; }

void iostream_init() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
}
//}}}

#define fst first
#define snd second
#define all(c) ((c).begin()), ((c).end())
#define TEST(s)                                                                \
  if (!(s)) {                                                                  \
    cout << __LINE__ << " " << #s << endl;                                     \
    exit(-1);                                                                  \
  }

struct hackenbush {
  int n;
  vector<vector<int>> adj;

  hackenbush(int n) : n(n), adj(n) {}
  void add_edge(int u, int v) {
    adj[u].push_back(v);
    if (u != v)
      adj[v].push_back(u);
  }

  // r is the only root connecting to the ground
  int grundy(int r) {
    vector<int> num(n), low(n);
    int t = 0;
    function<int(int, int)> dfs = [&](int p, int u) {
      num[u] = low[u] = ++t;
      int ans = 0;
      for (int v : adj[u]) {
        if (v == p) {
          p += 2 * n;
          continue;
        }
        if (num[v] == 0) {
          int res = dfs(u, v);
          low[u] = min(low[u], low[v]);
          if (low[v] > num[u])
            ans ^= (1 + res) ^ 1; // bridge
          else
            ans ^= res; // non bridge
        } else
          low[u] = min(low[u], num[v]);
      }
      if (p > n)
        p -= 2 * n;
      for (int v : adj[u])
        if (v != p && num[u] <= num[v])
          ans ^= 1;
      return ans;
    };
    return dfs(-1, r);
  }
};

int main() {
  iostream_init();

  int n;
  cin >> n;
  int ans = 0;
  hackenbush g(n);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    scanf("%d %d", &u, &v);
    --u;
    --v;
    g.add_edge(u, v);
  }
  cout << (g.grundy(0) ? "Alice" : "Bob") << endl;

  return 0;
}


Fixed submission:
// Template {{{
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;

#ifdef LOCAL
#include "contest.h"
#else
#define error(args...)
#endif

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
inline bool valid(int x, int w) { return 0 <= x && x < w; }

void iostream_init() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
}
//}}}

#define fst first
#define snd second
#define all(c) ((c).begin()), ((c).end())
#define TEST(s)                                                                \
  if (!(s)) {                                                                  \
    cout << __LINE__ << " " << #s << endl;                                     \
    exit(-1);                                                                  \
  }

struct hackenbush {
  int n;
  vector<vector<int>> adj;

  hackenbush(int n) : n(n), adj(n) {}
  void add_edge(int u, int v) {
    adj[u].push_back(v);
    if (u != v)
      adj[v].push_back(u);
  }

  // r is the only root connecting to the ground
  int grundy(int r) {
    vector<int> num(n), low(n);
    int t = 0;
    function<int(int, int)> dfs = [&](int p, int u) {
      num[u] = low[u] = ++t;
      int ans = 0;
      for (int v : adj[u]) {
        if (v == p) {
          p += 2 * n;
          continue;
        }
        if (num[v] == 0) {
          int res = dfs(u, v);
          low[u] = min(low[u], low[v]);
          if (low[v] > num[u])
            ans ^= (1 + res) ^ 1; // bridge
          else
            ans ^= res; // non bridge
        } else
          low[u] = min(low[u], num[v]);
      }
      if (p > n)
        p -= 2 * n;
      for (int v : adj[u])
        if (v != p && num[u] <= num[v])
          ans ^= 1;
      return ans;
    };
    return dfs(-1, r);
  }
};

int main() {
  iostream_init();

  int n;
  cin >> n;
  int ans = 0;
  hackenbush g(n);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    g.add_edge(u, v);
  }
  cout << (g.grundy(0) ? "Alice" : "Bob") << endl;

  return 0;
}