Problem p03278 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
const int nmax = 5005;
const long long mod = 1000 * 1000 * 1000 + 7;
vector<int> v[nmax];
int dp[nmax][nmax][2], newdp[nmax][2];
int pr[nmax];
long long ans;
int w[nmax], tt[nmax];
int n, i, a, b;
void dfs(int x) {
  w[x] = 1;
  for (int i = 0; i < v[x].size(); i++)
    if (!w[v[x][i]]) {
      tt[v[x][i]] = x;
      dfs(v[x][i]);
      w[x] += w[v[x][i]];
    }
  dp[x][1][0] = 1;
  int nod;
  for (int i = 0; i < v[x].size(); i++)
    if (v[x][i] != tt[x]) {
      nod = v[x][i];
      for (int j = 0; j <= w[x]; j++)
        for (int k = 0; k <= w[nod]; k++)
          for (int p1 = 0; p1 < 2; p1++)
            for (int p2 = 0; p2 < 2; p2++) {
              newdp[j + k][(p1 ^ p2)] = (1LL * newdp[j + k][(p1 ^ p2)] +
                                         1LL * dp[x][j][p1] * dp[nod][k][p2]) %
                                        mod;
              newdp[j][(p1 ^ p2 ^ 1)] =
                  (1LL * newdp[j][(p1 ^ p2 ^ 1)] +
                   1LL * dp[x][j][p1] *
                       ((1LL * dp[nod][k][p2] * pr[k]) % mod)) %
                  mod;
            }
      w[x] += w[nod];
      for (int j = 0; j <= w[x]; j++)
        for (int p = 0; p < 2; p++) {
          dp[x][j][p] = newdp[j][p];
          newdp[j][p] = 0;
        }
    }
}
int main() {
  // freopen("data.in","r",stdin);
  ios_base::sync_with_stdio(false);
  cin >> n;
  pr[0] = 1;
  for (i = 2; i <= n; i++)
    pr[i] = (1LL * pr[i - 2] * (i - 1)) % mod;
  for (i = 1; i <= n - 1; i++) {
    cin >> a >> b;
    v[a].push_back(b);
    v[b].push_back(a);
  }
  dfs(1);
  for (i = 1; i <= n; i++) {
    ans = (1LL * ans - 1LL * dp[1][i][1] * pr[i]) % mod;
    ans = (ans + mod) % mod;
    ans = (1LL * ans + 1LL * dp[1][i][0] * pr[i]) % mod;
  }
  cout << ans;
  return 0;
}


Fixed submission:
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
const int nmax = 5005;
const long long mod = 1000 * 1000 * 1000 + 7;
vector<int> v[nmax];
int dp[nmax][nmax][2], newdp[nmax][2];
int pr[nmax];
long long ans;
int w[nmax], tt[nmax];
int n, i, a, b;
void dfs(int x) {
  w[x] = 1;
  for (int i = 0; i < v[x].size(); i++)
    if (!w[v[x][i]]) {
      tt[v[x][i]] = x;
      dfs(v[x][i]);
    }
  dp[x][1][0] = 1;
  int nod;
  for (int i = 0; i < v[x].size(); i++)
    if (v[x][i] != tt[x]) {
      nod = v[x][i];
      for (int j = 0; j <= w[x]; j++)
        for (int k = 0; k <= w[nod]; k++)
          for (int p1 = 0; p1 < 2; p1++)
            for (int p2 = 0; p2 < 2; p2++) {
              newdp[j + k][(p1 ^ p2)] = (1LL * newdp[j + k][(p1 ^ p2)] +
                                         1LL * dp[x][j][p1] * dp[nod][k][p2]) %
                                        mod;
              newdp[j][(p1 ^ p2 ^ 1)] =
                  (1LL * newdp[j][(p1 ^ p2 ^ 1)] +
                   1LL * dp[x][j][p1] *
                       ((1LL * dp[nod][k][p2] * pr[k]) % mod)) %
                  mod;
            }
      w[x] += w[nod];
      for (int j = 0; j <= w[x]; j++)
        for (int p = 0; p < 2; p++) {
          dp[x][j][p] = newdp[j][p];
          newdp[j][p] = 0;
        }
    }
}
int main() {
  // freopen("data.in","r",stdin);
  ios_base::sync_with_stdio(false);
  cin >> n;
  pr[0] = 1;
  for (i = 2; i <= n; i++)
    pr[i] = (1LL * pr[i - 2] * (i - 1)) % mod;
  for (i = 1; i <= n - 1; i++) {
    cin >> a >> b;
    v[a].push_back(b);
    v[b].push_back(a);
  }
  dfs(1);
  for (i = 1; i <= n; i++) {
    ans = (1LL * ans - 1LL * dp[1][i][1] * pr[i]) % mod;
    ans = (ans + mod) % mod;
    ans = (1LL * ans + 1LL * dp[1][i][0] * pr[i]) % mod;
  }
  cout << ans;
  return 0;
}