Problem p02794 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;

const int N = 50;
vector<int> edges[N];
int tin[N], tout[N], timer, lca[N][N], p[N], add[N];
int ql[N], qr[N];
int n, m;

void dfs(int v, int _p) {
  tin[v] = timer++;
  p[v] = _p;
  for (int u : edges[v]) {
    if (u == _p)
      continue;
    dfs(u, v);
  }
  tout[v] = timer++;
}

bool ancestor(int v, int u) { return tin[v] <= tin[u] && tout[u] <= tout[v]; }

int calcLCA(int v, int u) {
  if (ancestor(v, u))
    return v;
  if (ancestor(u, v))
    return u;
  while (!ancestor(p[v], u))
    v = p[v];
  return p[v];
}

void prec() {
  dfs(0, 0);
  for (int v = 1; v <= n; v++) {
    for (int u = 1; u <= n; u++) {
      lca[v][u] = calcLCA(v, u);
    }
  }
}

int getcnt;

void dfsForC(int v, int p) {
  for (int u : edges[v]) {
    if (u == p)
      continue;
    dfsForC(u, v);
    add[v] += add[u];
    if (add[u] > 0)
      getcnt--;
  }
}

int calcMask(int mask) {
  memset(add, 0, sizeof add);
  for (int i = 0; i < m; i++) {
    if (!(mask & (1 << i)))
      continue;
    int v = ql[i], u = qr[i], w = lca[v][u];
    add[v]++, add[u]++, add[w] -= 2;
  }
  getcnt = n - 1;
  dfsForC(0, 0);
  return getcnt;
}

int getSign(int mask) {
  int cnt = __builtin_popcount(mask);
  if (cnt % 2 == 0)
    return 1;
  else
    return -1;
}

void solve() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int v, u;
    cin >> v >> u;
    v--, u--;
    edges[v].push_back(u);
    edges[u].push_back(v);
  }
  cin >> m;
  for (int i = 0; i < m; i++) {
    cin >> ql[i] >> qr[i];
    ql[i]--, qr[i]--;
  }
  prec();
  long long ans = 0;
  for (int mask = 0; mask < (1 << m); mask++) {
    int sign = getSign(mask);
    ans += 1LL * sign * (1LL << calcMask(mask));
  }
  cout << ans;
}

int main() {
  ios::sync_with_stdio(NULL), cin.tie(0), cout.tie(0);
  cout.setf(ios::fixed), cout.precision(20);
  solve();
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

const int N = 50;
vector<int> edges[N];
int tin[N], tout[N], timer, lca[N][N], p[N], add[N];
int ql[N], qr[N];
int n, m;

void dfs(int v, int _p) {
  tin[v] = timer++;
  p[v] = _p;
  for (int u : edges[v]) {
    if (u == _p)
      continue;
    dfs(u, v);
  }
  tout[v] = timer++;
}

bool ancestor(int v, int u) { return tin[v] <= tin[u] && tout[u] <= tout[v]; }

int calcLCA(int v, int u) {
  if (ancestor(v, u))
    return v;
  if (ancestor(u, v))
    return u;
  while (!ancestor(p[v], u))
    v = p[v];
  return p[v];
}

void prec() {
  dfs(0, 0);
  for (int v = 0; v < n; v++) {
    for (int u = 0; u < n; u++) {
      lca[v][u] = calcLCA(v, u);
    }
  }
}

int getcnt;

void dfsForC(int v, int p) {
  for (int u : edges[v]) {
    if (u == p)
      continue;
    dfsForC(u, v);
    add[v] += add[u];
    if (add[u] > 0)
      getcnt--;
  }
}

int calcMask(int mask) {
  memset(add, 0, sizeof add);
  for (int i = 0; i < m; i++) {
    if (!(mask & (1 << i)))
      continue;
    int v = ql[i], u = qr[i], w = lca[v][u];
    add[v]++, add[u]++, add[w] -= 2;
  }
  getcnt = n - 1;
  dfsForC(0, 0);
  return getcnt;
}

int getSign(int mask) {
  int cnt = __builtin_popcount(mask);
  if (cnt % 2 == 0)
    return 1;
  else
    return -1;
}

void solve() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int v, u;
    cin >> v >> u;
    v--, u--;
    edges[v].push_back(u);
    edges[u].push_back(v);
  }
  cin >> m;
  for (int i = 0; i < m; i++) {
    cin >> ql[i] >> qr[i];
    ql[i]--, qr[i]--;
  }
  prec();
  long long ans = 0;
  for (int mask = 0; mask < (1 << m); mask++) {
    int sign = getSign(mask);
    ans += 1LL * sign * (1LL << calcMask(mask));
  }
  cout << ans;
}

int main() {
  ios::sync_with_stdio(NULL), cin.tie(0), cout.tie(0);
  cout.setf(ios::fixed), cout.precision(20);
  solve();
}