Problem p03278 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define End exit(0)
#define LL long long
#define mp make_pair
#define SZ(x) ((int)x.size())
#define GO cerr << "GO" << endl
#define DE(x) cout << #x << " = " << x << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)

void proc_status() {
  freopen("/proc/self/status", "r", stdin);
  string s;
  while (getline(cin, s))
    if (s[2] == 'P') {
      cerr << s << endl;
      return;
    }
}

template <typename T> inline T read() {
  register T x = 0;
  register char c;
  register int f(1);
  while (!isdigit(c = getchar()))
    if (c == '-')
      f = -1;
  while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getchar()))
    ;
  return x * f;
}

template <typename T> inline bool chkmin(T &a, T b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T> inline bool chkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}

const int maxN = 5000 + 2;
const int mod = 1e9 + 7;

int n;
int ver[maxN << 1], nxt[maxN << 1], head[maxN + 2];
int dp[maxN + 2][maxN + 2], tmp[maxN + 2], size[maxN + 2], g[maxN + 2];

inline void Inc(int &x) { x < 0 ? x += mod : 0; }
inline void Dec(int &x) { x >= mod ? x -= mod : 0; }

void link(int u, int v) {
  static int ecnt = 0;
  ver[++ecnt] = v, nxt[ecnt] = head[u], head[u] = ecnt;
}

void dfs(int u, int fa) {
  dp[u][1] = 1;
  size[u] = 1;
  for (int i = head[u]; i; i = nxt[i]) {
    int v = ver[i];
    if (v == fa)
      continue;
    dfs(v, u);
    for (int i = 0; i <= size[u]; ++i)
      for (int j = 0; j <= size[v]; ++j)
        Dec(tmp[i + j] += 1ll * dp[u][i] * dp[v][j] % mod);
    size[u] += size[v];
    for (int i = 0; i <= size[u]; ++i)
      dp[u][i] = tmp[i], tmp[i] = 0;
  }
  for (int i = 1; i <= size[u]; ++i)
    Inc(dp[u][0] -= 1ll * dp[u][i] * g[i] % mod);
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("xhc.in", "r", stdin);
  freopen("xhc.out", "w", stdout);
#endif
  n = read<int>();
  for (int i = 1; i < n; ++i) {
    int u = read<int>(), v = read<int>();
    link(u, v), link(v, u);
  }
  g[0] = 1;
  for (int i = 2; i <= n; ++i)
    g[i] = 1ll * g[i - 2] * (i - 1) % mod;
  dfs(1, 0);
  printf("%d\n", (mod - dp[1][0]) % mod);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define End exit(0)
#define LL long long
#define mp make_pair
#define SZ(x) ((int)x.size())
#define GO cerr << "GO" << endl
#define DE(x) cout << #x << " = " << x << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)

void proc_status() {
  freopen("/proc/self/status", "r", stdin);
  string s;
  while (getline(cin, s))
    if (s[2] == 'P') {
      cerr << s << endl;
      return;
    }
}

template <typename T> inline T read() {
  register T x = 0;
  register char c;
  register int f(1);
  while (!isdigit(c = getchar()))
    if (c == '-')
      f = -1;
  while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getchar()))
    ;
  return x * f;
}

template <typename T> inline bool chkmin(T &a, T b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T> inline bool chkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}

const int maxN = 5000 + 2;
const int mod = 1e9 + 7;

int n;
int ver[maxN << 1], nxt[maxN << 1], head[maxN + 2];
int dp[maxN + 2][maxN + 2], tmp[maxN + 2], size[maxN + 2], g[maxN + 2];

inline void Inc(int &x) { x < 0 ? x += mod : 0; }
inline void Dec(int &x) { x >= mod ? x -= mod : 0; }

void link(int u, int v) {
  static int ecnt = 0;
  ver[++ecnt] = v, nxt[ecnt] = head[u], head[u] = ecnt;
}

void dfs(int u, int fa) {
  dp[u][1] = 1;
  size[u] = 1;
  for (int i = head[u]; i; i = nxt[i]) {
    int v = ver[i];
    if (v == fa)
      continue;
    dfs(v, u);
    for (int i = 0; i <= size[u]; ++i)
      for (int j = 0; j <= size[v]; ++j)
        Dec(tmp[i + j] += 1ll * dp[u][i] * dp[v][j] % mod);
    size[u] += size[v];
    for (int i = 0; i <= size[u]; ++i)
      dp[u][i] = tmp[i], tmp[i] = 0;
  }
  for (int i = 1; i <= size[u]; ++i)
    Inc(dp[u][0] -= 1ll * dp[u][i] * g[i] % mod);
}

int main() {
  n = read<int>();
  for (int i = 1; i < n; ++i) {
    int u = read<int>(), v = read<int>();
    link(u, v), link(v, u);
  }
  g[0] = 1;
  for (int i = 2; i <= n; ++i)
    g[i] = 1ll * g[i - 2] * (i - 1) % mod;
  dfs(1, 0);
  printf("%d\n", (mod - dp[1][0]) % mod);
  return 0;
}