Problem p03949 (C++)

Buggy submission (status: Time Limit Exceeded):
#define ONLINE_JUDGE
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef pair<ll, ll> pl;
typedef vector<pl> vp;
const ll INF = 1001001001;
const ll LINF = 1001001001001001001;
const ll D4[] = {0, 1, 0, -1, 0};
const ll D8[] = {0, 1, 1, 0, -1, -1, 1, -1, 0};
#define _overload3(_1, _2, _3, name, ...) name
#define _rep2(i, n) for (ll i = 0; i < (n); ++i)
#define _rep3(i, a, b) for (ll i = (a); i < (b); ++i)
#define rep(...) _overload3(__VA_ARGS__, _rep3, _rep2)(__VA_ARGS__)
#define _repe2(i, n) for (ll i = 0; i <= (n); ++i)
#define _repe3(i, a, b) for (ll i = (a); i <= (b); ++i)
#define repe(...) _overload3(__VA_ARGS__, _repe3, _repe2)(__VA_ARGS__)
#define _rrep2(i, n) for (ll i = (n)-1; i >= 0; i--)
#define _rrep3(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define rrep(...) _overload3(__VA_ARGS__, _rrep3, _rrep2)(__VA_ARGS__)
#define all(x) (x).begin(), (x).end()
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> using pq = priority_queue<T, vector<T>, greater<T>>;
const string YES = "Yes";
const string NO = "No";

ll N;
vl A;
vl B;
ll K;
vl V;
vl P;

void solve();

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cin >> N;
  A = vl(N - 1);
  B = vl(N - 1);
  for (int i = 0; i < N - 1; ++i) {
    cin >> A[i];
    cin >> B[i];
  }
  cin >> K;
  V = vl(K);
  P = vl(K);
  for (int i = 0; i < K; ++i) {
    cin >> V[i];
    cin >> P[i];
  }
  solve();
}

// 1 ≦ N ≦ 10^5
// 1 ≦ K ≦ N
// 1 ≦ A_i, B_i ≦ N (1 ≦ i ≦ N - 1)
// 1 ≦ V_j ≦ N (1 ≦ j ≦ K) (21:18, 制約の誤記を修正)
// 0 ≦ P_j ≦ 10^6 (1 ≦ j ≦ K)
// 与えられるグラフは木になることが保証される
// V_j はすべて相異なる

vvl g;
vl a, mx, mi, ans;

void dfs2(ll x = 0, ll p = 0) {
  for (ll to : g[x]) {
    if (to == p)
      continue;
    if (ans[to] != -1 && (ans[to] < mi[to] || mx[to] < ans[to])) {
      cout << NO << endl;
      exit(0);
    }
    if (mi[to] <= ans[x] + 1 && ans[x] + 1 <= mx[to])
      ans[to] = ans[x] + 1;
    else if (mi[to] <= ans[x] - 1 && ans[x] - 1 <= mx[to])
      ans[to] = ans[x] - 1;
    else {
      cout << NO << endl;
      exit(0);
    }
    dfs2(to, x);
  }
}

void dfs(ll x = 0, ll p = -1) {
  for (ll to : g[x]) {
    if (to == p)
      continue;
    dfs(to, x);
    chmin(mx[x], mx[to] + 1);
    chmax(mi[x], mi[to] - 1);
  }
  if (a[x] == -1 && x != 0)
    return;
  if (a[x] != -1) {
    ans[x] = a[x];
    mx[x] = mi[x] = a[x];
  } else {
    ans[x] = mx[x];
  }
  dfs2(x, p);
}

// ll N, vl A, vl B, ll K, vl V, vl P
// 残りのすべての頂点に書き込む整数を工夫することで木が条件を満たすようにできるならば
// Yes を、できないならば No を出力せよ。 条件を満たせる場合、追加で N
// 行出力せよ。このうちの v (1 ≦ v ≦ N) 行目には、頂点 v
// に書かれる整数を出力せよ。条件を満たすような整数の書き込み方が複数ある場合、そのうちいずれかひとつを出力すればよい。
void solve() {
  g.resize(N);
  rep(i, N - 1) {
    g[A[i] - 1].push_back(B[i] - 1);
    g[B[i] - 1].push_back(A[i] - 1);
  }

  mx.resize(N, INF);
  mi.resize(N, 0);
  a.resize(N, -1);
  ans.resize(N, -1);
  rep(i, K) a[V[i] - 1] = P[i];
  dfs();

  cout << YES << endl;
  rep(i, N) cout << ans[i] << endl;
}


Fixed submission:
#define ONLINE_JUDGE
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef pair<ll, ll> pl;
typedef vector<pl> vp;
const ll INF = 1001001001;
const ll LINF = 1001001001001001001;
const ll D4[] = {0, 1, 0, -1, 0};
const ll D8[] = {0, 1, 1, 0, -1, -1, 1, -1, 0};
#define _overload3(_1, _2, _3, name, ...) name
#define _rep2(i, n) for (ll i = 0; i < (n); ++i)
#define _rep3(i, a, b) for (ll i = (a); i < (b); ++i)
#define rep(...) _overload3(__VA_ARGS__, _rep3, _rep2)(__VA_ARGS__)
#define _repe2(i, n) for (ll i = 0; i <= (n); ++i)
#define _repe3(i, a, b) for (ll i = (a); i <= (b); ++i)
#define repe(...) _overload3(__VA_ARGS__, _repe3, _repe2)(__VA_ARGS__)
#define _rrep2(i, n) for (ll i = (n)-1; i >= 0; i--)
#define _rrep3(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define rrep(...) _overload3(__VA_ARGS__, _rrep3, _rrep2)(__VA_ARGS__)
#define all(x) (x).begin(), (x).end()
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> using pq = priority_queue<T, vector<T>, greater<T>>;
const string YES = "Yes";
const string NO = "No";

ll N;
vl A;
vl B;
ll K;
vl V;
vl P;

void solve();

int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cin >> N;
  A = vl(N - 1);
  B = vl(N - 1);
  for (int i = 0; i < N - 1; ++i) {
    cin >> A[i];
    cin >> B[i];
  }
  cin >> K;
  V = vl(K);
  P = vl(K);
  for (int i = 0; i < K; ++i) {
    cin >> V[i];
    cin >> P[i];
  }
  solve();
}

// 1 ≦ N ≦ 10^5
// 1 ≦ K ≦ N
// 1 ≦ A_i, B_i ≦ N (1 ≦ i ≦ N - 1)
// 1 ≦ V_j ≦ N (1 ≦ j ≦ K) (21:18, 制約の誤記を修正)
// 0 ≦ P_j ≦ 10^6 (1 ≦ j ≦ K)
// 与えられるグラフは木になることが保証される
// V_j はすべて相異なる

vvl g;
vl a, mx, mi, ans;

void dfs2(ll x = 0, ll p = 0) {
  for (ll to : g[x]) {
    if (to == p)
      continue;
    if (ans[to] != -1) {
      if (abs(ans[x] - ans[to]) != 1) {
        cout << NO << endl;
        exit(0);
      }
      continue;
    }
    if (mi[to] <= ans[x] + 1 && ans[x] + 1 <= mx[to])
      ans[to] = ans[x] + 1;
    else if (mi[to] <= ans[x] - 1 && ans[x] - 1 <= mx[to])
      ans[to] = ans[x] - 1;
    else {
      cout << NO << endl;
      exit(0);
    }
    dfs2(to, x);
  }
}

void dfs(ll x = 0, ll p = -1) {
  for (ll to : g[x]) {
    if (to == p)
      continue;
    dfs(to, x);
    chmin(mx[x], mx[to] + 1);
    chmax(mi[x], mi[to] - 1);
  }
  if (a[x] == -1 && x != 0)
    return;
  if (a[x] != -1) {
    ans[x] = a[x];
    mx[x] = mi[x] = a[x];
  } else {
    ans[x] = mx[x];
  }
  dfs2(x, p);
}

// ll N, vl A, vl B, ll K, vl V, vl P
// 残りのすべての頂点に書き込む整数を工夫することで木が条件を満たすようにできるならば
// Yes を、できないならば No を出力せよ。 条件を満たせる場合、追加で N
// 行出力せよ。このうちの v (1 ≦ v ≦ N) 行目には、頂点 v
// に書かれる整数を出力せよ。条件を満たすような整数の書き込み方が複数ある場合、そのうちいずれかひとつを出力すればよい。
void solve() {
  g.resize(N);
  rep(i, N - 1) {
    g[A[i] - 1].push_back(B[i] - 1);
    g[B[i] - 1].push_back(A[i] - 1);
  }

  mx.resize(N, INF);
  mi.resize(N, 0);
  a.resize(N, -1);
  ans.resize(N, -1);
  rep(i, K) a[V[i] - 1] = P[i];
  dfs();

  cout << YES << endl;
  rep(i, N) cout << ans[i] << endl;
}