Problem p03949 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define N 1000010
using namespace std;

int n, k;
const int INF[2] = {20000000, 20000001};
vector<int> edge[N];

bool vis[N];
int val[N];

int up[N], down[N];
bool dfs(int u, int fa, bool odd) {
  up[u] = INF[odd];
  down[u] = -INF[odd];
  for (int i = 0; i < edge[u].size(); ++i) {
    int v = edge[u][i];
    if (v != fa) {
      if (!dfs(v, u, odd ^ 1))
        return false;
      up[u] = min(up[v] + 1, up[u]);
      down[u] = max(down[v] - 1, down[u]);
    }
  }

  if (down[u] > up[u])
    return false;
  if (vis[u]) {
    if (down[u] > val[u] || up[u] < val[u])
      return false;
    down[u] = up[u] = val[u];
  }
  if ((abs(down[u]) & 1) != odd || (abs(up[u]) & 1) != odd)
    return false;
  return true;
}

void getAns(int u, int fa, bool odd) {
  for (int i = 0; i < edge[u].size(); ++i) {
    int v = edge[u][i];
    if (v != fa) {
      if (!vis[v]) {
        if (val[u] + 1 <= up[u] && val[u] + 1 >= down[u])
          val[v] = val[u] + 1;
        else
          val[v] = val[u] - 1;
      }
      getAns(v, u, odd ^ 1);
    }
  }
}

bool check(int u, int fa) {
  for (int i = 0; i < edge[u].size(); ++i) {
    int v = edge[u][i];
    if (v == fa)
      continue;
    if (abs(val[u] - val[v]) != 1)
      return false;
    if (!check(v, u))
      return false;
  }
  return true;
}

int a[N], b[N];
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    edge[u].push_back(v);
    edge[v].push_back(u);
  }

  scanf("%d", &k);
  for (int i = 1; i <= k; ++i) {
    scanf("%d%d", &a[i], &b[i]);
    val[a[i]] = b[i];
    vis[a[i]] = 1;
  }
  if (!dfs(a[1], 0, (b[1] & 1))) {
    puts("No");
  } else {
    val[a[1]] = b[1];
    getAns(a[1], 0, b[1] & 1);
    assert(check(1, 0));
    puts("Yes");
    for (int i = 1; i <= n; ++i)
      printf("%d\n", val[i]);
  }
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#define N 1000010
using namespace std;

int n, k;
const int INF[2] = {20000000, 20000001};
vector<int> edge[N];

bool vis[N];
int val[N];

int up[N], down[N];
bool dfs(int u, int fa, bool odd) {
  up[u] = INF[odd];
  down[u] = -INF[odd];
  for (int i = 0; i < edge[u].size(); ++i) {
    int v = edge[u][i];
    if (v != fa) {
      if (!dfs(v, u, odd ^ 1))
        return false;
      up[u] = min(up[v] + 1, up[u]);
      down[u] = max(down[v] - 1, down[u]);
    }
  }

  if (down[u] > up[u])
    return false;
  if (vis[u]) {
    if (down[u] > val[u] || up[u] < val[u])
      return false;
    down[u] = up[u] = val[u];
  }
  if ((abs(down[u]) & 1) != odd || (abs(up[u]) & 1) != odd)
    return false;
  return true;
}

void getAns(int u, int fa, bool odd) {
  for (int i = 0; i < edge[u].size(); ++i) {
    int v = edge[u][i];
    if (v != fa) {
      if (!vis[v]) {
        if (val[u] + 1 <= up[v] && val[u] + 1 >= down[v])
          val[v] = val[u] + 1;
        else
          val[v] = val[u] - 1;
      }
      getAns(v, u, odd ^ 1);
    }
  }
}

bool check(int u, int fa) {
  for (int i = 0; i < edge[u].size(); ++i) {
    int v = edge[u][i];
    if (v == fa)
      continue;
    if (abs(val[u] - val[v]) != 1)
      return false;
    if (!check(v, u))
      return false;
  }
  return true;
}

int a[N], b[N];
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    edge[u].push_back(v);
    edge[v].push_back(u);
  }

  scanf("%d", &k);
  for (int i = 1; i <= k; ++i) {
    scanf("%d%d", &a[i], &b[i]);
    val[a[i]] = b[i];
    vis[a[i]] = 1;
  }
  if (!dfs(a[1], 0, (b[1] & 1))) {
    puts("No");
  } else {
    val[a[1]] = b[1];
    getAns(a[1], 0, b[1] & 1);
    assert(check(1, 0));
    puts("Yes");
    for (int i = 1; i <= n; ++i)
      printf("%d\n", val[i]);
  }
}