Problem p03949 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstddef>
#include <deque>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// Yay!!
#define endl codeforces

// macros for iterator
#define ALL(v) std::begin(v), std::end(v)
#define ALLR(v) std::rbegin(v), std::rend(v)

// alias
using ll = std::int64_t;
using ull = std::uint64_t;
using pii = std::pair<int, int>;
using tii = std::tuple<int, int, int>;
using pll = std::pair<ll, ll>;
using tll = std::tuple<ll, ll, ll>;
template <typename T> using vec = std::vector<T>;
template <typename T> using vvec = vec<vec<T>>;

// variadic min/max
template <typename T> const T &var_min(const T &t) { return t; }
template <typename T> const T &var_max(const T &t) { return t; }
template <typename T, typename... Tail>
const T &var_min(const T &t, const Tail &...tail) {
  return std::min(t, var_min(tail...));
}
template <typename T, typename... Tail>
const T &var_max(const T &t, const Tail &...tail) {
  return std::max(t, var_max(tail...));
}

// variadic chmin/chmax
template <typename T, typename... Tail> void chmin(T &t, const Tail &...tail) {
  t = var_min(t, tail...);
}
template <typename T, typename... Tail> void chmax(T &t, const Tail &...tail) {
  t = var_max(t, tail...);
}

// multi demension array
template <typename T, std::size_t Head, std::size_t... Tail>
struct multi_dim_array {
  using type = std::array<typename multi_dim_array<T, Tail...>::type, Head>;
};
template <typename T, std::size_t Head> struct multi_dim_array<T, Head> {
  using type = std::array<T, Head>;
};
template <typename T, std::size_t... Args>
using mdarray = typename multi_dim_array<T, Args...>::type;

// make multi dimension vector
template <typename T> vec<T> make_v(ssize_t sz) { return vec<T>(sz); }
template <typename T, typename... Tail> auto make_v(ssize_t hs, Tail &&...ts) {
  auto v = std::move(make_v<T>(std::forward<Tail>(ts)...));
  return vec<decltype(v)>(hs, v);
}

// init
namespace init__ {
struct InitIO {
  InitIO() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << std::fixed << std::setprecision(30);
  }
} init_io;
} // namespace init__

namespace graph {

using Node = ll;
using Weight = ll;
using Edge = std::pair<Node, Weight>;

template <bool Directed> struct Graph : public vvec<Edge> {
  using vvec<Edge>::vvec;

  void add_edge(Node f, Node t, Weight w = 1) {
    (*this)[f].emplace_back(t, w);
    if (!Directed)
      (*this)[t].emplace_back(f, w);
  }

  Graph<Directed> build_inv() const {
    Graph<Directed> ret(this->size());
    for (Node i = 0; i < this->size(); i++) {
      for (const Edge &e : (*this)[i]) {
        Node j;
        Weight w;
        std::tie(j, w) = e;
        if (!Directed && j < i)
          continue;
        ret.add_edge(j, i, w);
      }
    }

    return ret;
  }
};

template <typename Iterator> class dst_iterator {
  Iterator ite;

public:
  dst_iterator(Iterator ite) : ite(ite) {}

  bool operator==(const dst_iterator<Iterator> &oth) const {
    return ite == oth.ite;
  }

  bool operator!=(const dst_iterator<Iterator> &oth) const {
    return !(*this == oth);
  }

  bool operator<(const dst_iterator<Iterator> &oth) const {
    return ite < oth.ite;
  }

  bool operator>(const dst_iterator<Iterator> &oth) const {
    return ite > oth.ite;
  }

  bool operator<=(const dst_iterator<Iterator> &oth) const {
    return ite <= oth.ite;
  }

  bool operator>=(const dst_iterator<Iterator> &oth) const {
    return ite >= oth.ite;
  }

  const Node &operator*() { return ite->first; }

  const Node &operator*() const { return ite->first; }

  dst_iterator operator++() {
    ++ite;
    return ite;
  }
};

class dst_iteration {
  using ite_type = vec<Edge>::const_iterator;
  const vec<Edge> &edges;

public:
  dst_iteration(const vec<Edge> &edges) : edges(edges) {}

  auto begin() const { return dst_iterator<ite_type>(edges.cbegin()); }

  auto end() const { return dst_iterator<ite_type>(edges.cend()); }
};

dst_iteration dst(const vec<Edge> &edges) { return dst_iteration(edges); }

} // namespace graph

const ll inf = 5e15;

struct Solver {
  ll n, k;
  graph::Graph<false> tree;
  vec<ll> val;
  std::queue<ll> que;
  vec<ll> par;
  vec<pll> ranges;
  const pll err = pll(-inf, -inf), init = pll(inf, inf);

  Solver(ll n) : n(n), tree(n), val(n, -1), par(n), ranges(n) {
    for (ll i = 1; i < n; i++) {
      ll a, b;
      std::cin >> a >> b;
      tree.add_edge(a - 1, b - 1);
    }

    std::cin >> k;
    for (ll i = 0; i < k; i++) {
      ll v, p;
      std::cin >> v >> p;
      val[v - 1] = p;
    }
  }

  bool is_init(pll p) {
    ll l, r;
    std::tie(l, r) = p;
    return inf <= std::max(std::abs(l), std::abs(r));
  }

  pll merge(pll p, pll q) {
    if (p > q)
      std::swap(p, q);
    if (p == err)
      return p;
    if (is_init(p))
      return init;
    if (is_init(q))
      return p;
    ll a, b, c, d;
    std::tie(a, b) = p;
    std::tie(c, d) = q;
    bool o1 = std::abs(a) & 1;
    bool o2 = std::abs(c) & 1;
    if (o1 ^ o2)
      return err;
    ll x = std::max(a, c), y = std::min(b, d);
    if (y < x)
      return err;
    return pll(x, y);
  }

  bool valid(pll rng, ll v) {
    ll l, r;
    std::tie(l, r) = rng;
    return l <= v && v <= r;
  }

  bool dfs(ll cur, ll pre) {
    par[cur] = pre;
    pll rng = (val[cur] == -1 ? init : pll(val[cur], val[cur]));
    if (val[cur] == -1)
      que.push(cur);
    for (ll nxt : graph::dst(tree[cur])) {
      if (nxt == pre)
        continue;
      if (!dfs(nxt, cur))
        return false;
      ll l, r;
      std::tie(l, r) = ranges[nxt];
      rng = merge(rng, pll(l - 1, r + 1));
    }
    ranges[cur] = rng;
    return rng != err;
  }

  void write() {
    while (que.size()) {
      ll cur = que.front();
      que.pop();
      ll pv = val[par[cur]];
      if (valid(ranges[cur], pv + 1))
        val[cur] = pv + 1;
      else
        val[cur] = pv - 1;
    }
  }

  vec<ll> solve() {
    for (ll i = 0; i < n; i++) {
      if (val[i] == -1)
        continue;
      if (!dfs(i, -1))
        return vec<ll>();
    }
    write();
    return val;
  }
};

int main() {
  ll n;
  std::cin >> n;
  Solver solver(n);
  auto ans = solver.solve();
  if (ans.empty()) {
    std::cout << "No\n";
  } else {
    std::cout << "Yes\n";
    for (ll e : ans)
      std::cout << e << "\n";
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstddef>
#include <deque>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// Yay!!
#define endl codeforces

// macros for iterator
#define ALL(v) std::begin(v), std::end(v)
#define ALLR(v) std::rbegin(v), std::rend(v)

// alias
using ll = std::int64_t;
using ull = std::uint64_t;
using pii = std::pair<int, int>;
using tii = std::tuple<int, int, int>;
using pll = std::pair<ll, ll>;
using tll = std::tuple<ll, ll, ll>;
template <typename T> using vec = std::vector<T>;
template <typename T> using vvec = vec<vec<T>>;

// variadic min/max
template <typename T> const T &var_min(const T &t) { return t; }
template <typename T> const T &var_max(const T &t) { return t; }
template <typename T, typename... Tail>
const T &var_min(const T &t, const Tail &...tail) {
  return std::min(t, var_min(tail...));
}
template <typename T, typename... Tail>
const T &var_max(const T &t, const Tail &...tail) {
  return std::max(t, var_max(tail...));
}

// variadic chmin/chmax
template <typename T, typename... Tail> void chmin(T &t, const Tail &...tail) {
  t = var_min(t, tail...);
}
template <typename T, typename... Tail> void chmax(T &t, const Tail &...tail) {
  t = var_max(t, tail...);
}

// multi demension array
template <typename T, std::size_t Head, std::size_t... Tail>
struct multi_dim_array {
  using type = std::array<typename multi_dim_array<T, Tail...>::type, Head>;
};
template <typename T, std::size_t Head> struct multi_dim_array<T, Head> {
  using type = std::array<T, Head>;
};
template <typename T, std::size_t... Args>
using mdarray = typename multi_dim_array<T, Args...>::type;

// make multi dimension vector
template <typename T> vec<T> make_v(ssize_t sz) { return vec<T>(sz); }
template <typename T, typename... Tail> auto make_v(ssize_t hs, Tail &&...ts) {
  auto v = std::move(make_v<T>(std::forward<Tail>(ts)...));
  return vec<decltype(v)>(hs, v);
}

// init
namespace init__ {
struct InitIO {
  InitIO() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << std::fixed << std::setprecision(30);
  }
} init_io;
} // namespace init__

namespace graph {

using Node = ll;
using Weight = ll;
using Edge = std::pair<Node, Weight>;

template <bool Directed> struct Graph : public vvec<Edge> {
  using vvec<Edge>::vvec;

  void add_edge(Node f, Node t, Weight w = 1) {
    (*this)[f].emplace_back(t, w);
    if (!Directed)
      (*this)[t].emplace_back(f, w);
  }

  Graph<Directed> build_inv() const {
    Graph<Directed> ret(this->size());
    for (Node i = 0; i < this->size(); i++) {
      for (const Edge &e : (*this)[i]) {
        Node j;
        Weight w;
        std::tie(j, w) = e;
        if (!Directed && j < i)
          continue;
        ret.add_edge(j, i, w);
      }
    }

    return ret;
  }
};

template <typename Iterator> class dst_iterator {
  Iterator ite;

public:
  dst_iterator(Iterator ite) : ite(ite) {}

  bool operator==(const dst_iterator<Iterator> &oth) const {
    return ite == oth.ite;
  }

  bool operator!=(const dst_iterator<Iterator> &oth) const {
    return !(*this == oth);
  }

  bool operator<(const dst_iterator<Iterator> &oth) const {
    return ite < oth.ite;
  }

  bool operator>(const dst_iterator<Iterator> &oth) const {
    return ite > oth.ite;
  }

  bool operator<=(const dst_iterator<Iterator> &oth) const {
    return ite <= oth.ite;
  }

  bool operator>=(const dst_iterator<Iterator> &oth) const {
    return ite >= oth.ite;
  }

  const Node &operator*() { return ite->first; }

  const Node &operator*() const { return ite->first; }

  dst_iterator operator++() {
    ++ite;
    return ite;
  }
};

class dst_iteration {
  using ite_type = vec<Edge>::const_iterator;
  const vec<Edge> &edges;

public:
  dst_iteration(const vec<Edge> &edges) : edges(edges) {}

  auto begin() const { return dst_iterator<ite_type>(edges.cbegin()); }

  auto end() const { return dst_iterator<ite_type>(edges.cend()); }
};

dst_iteration dst(const vec<Edge> &edges) { return dst_iteration(edges); }

} // namespace graph

const ll inf = 5e15;

struct Solver {
  ll n, k;
  graph::Graph<false> tree;
  vec<ll> val;
  std::queue<ll> que;
  vec<ll> par;
  vec<pll> ranges;
  const pll err = pll(-inf, -inf), init = pll(inf, inf);

  Solver(ll n) : n(n), tree(n), val(n, -1), par(n), ranges(n) {
    for (ll i = 1; i < n; i++) {
      ll a, b;
      std::cin >> a >> b;
      tree.add_edge(a - 1, b - 1);
    }

    std::cin >> k;
    for (ll i = 0; i < k; i++) {
      ll v, p;
      std::cin >> v >> p;
      val[v - 1] = p;
    }
  }

  bool is_init(pll p) {
    ll l, r;
    std::tie(l, r) = p;
    return inf <= std::max(std::abs(l), std::abs(r));
  }

  pll merge(pll p, pll q) {
    if (p > q)
      std::swap(p, q);
    if (p == err)
      return p;
    if (is_init(p))
      return init;
    if (is_init(q))
      return p;
    ll a, b, c, d;
    std::tie(a, b) = p;
    std::tie(c, d) = q;
    bool o1 = std::abs(a) & 1;
    bool o2 = std::abs(c) & 1;
    if (o1 ^ o2)
      return err;
    ll x = std::max(a, c), y = std::min(b, d);
    if (y < x)
      return err;
    return pll(x, y);
  }

  bool valid(pll rng, ll v) {
    ll l, r;
    std::tie(l, r) = rng;
    return l <= v && v <= r;
  }

  bool dfs(ll cur, ll pre) {
    par[cur] = pre;
    pll rng = (val[cur] == -1 ? init : pll(val[cur], val[cur]));
    if (val[cur] == -1)
      que.push(cur);
    for (ll nxt : graph::dst(tree[cur])) {
      if (nxt == pre)
        continue;
      if (!dfs(nxt, cur))
        return false;
      ll l, r;
      std::tie(l, r) = ranges[nxt];
      rng = merge(rng, pll(l - 1, r + 1));
    }
    ranges[cur] = rng;
    return rng != err;
  }

  void write() {
    while (que.size()) {
      ll cur = que.front();
      que.pop();
      ll pv = val[par[cur]];
      if (valid(ranges[cur], pv + 1))
        val[cur] = pv + 1;
      else
        val[cur] = pv - 1;
    }
  }

  vec<ll> solve() {
    for (ll i = 0; i < n; i++) {
      if (val[i] == -1)
        continue;
      if (!dfs(i, -1))
        return vec<ll>();
      break;
    }
    write();
    return val;
  }
};

int main() {
  ll n;
  std::cin >> n;
  Solver solver(n);
  auto ans = solver.solve();
  if (ans.empty()) {
    std::cout << "No\n";
  } else {
    std::cout << "Yes\n";
    for (ll e : ans)
      std::cout << e << "\n";
  }
  return 0;
}