Submission #521553

#TimeUsernameProblemLanguageResultExecution timeMemory
521553CyanmondRace (IOI11_race)C++17
100 / 100
350 ms85276 KiB
#line 1 "paper.cpp" #include <bits/stdc++.h> #line 3 "library2/utility/infty.hpp" template <typename T, T Div = 2> constexpr T infty = std::numeric_limits<T>::max() / Div; #line 3 "library2/utility/len.hpp" template <class Container> int len(const Container&c){ return static_cast<int>(std::size(c)); } #line 2 "library2/utility/rec_lambda.hpp" template <class F> class RecursiveLambda { F f; public: explicit constexpr RecursiveLambda(F &&f_) : f(std::forward<F>(f_)) {} template <class... Args> constexpr auto operator()(Args &&...args) const { return f(*this, std::forward<Args>(args)...); } }; template <class F> constexpr decltype(auto) rec_lambda(F &&f) { return RecursiveLambda<F>(std::forward<F>(f)); } #line 3 "library2/utility/rep.hpp" class Range { struct Iterator { int itr; constexpr Iterator(const int pos) noexcept : itr(pos) {} constexpr void operator++() noexcept { ++itr; } constexpr bool operator!=(const Iterator &other) const noexcept { return itr != other.itr; } constexpr int operator*() const noexcept { return itr; } }; const Iterator first, last; public: explicit constexpr Range(const int f, const int l) noexcept : first(f), last(std::max(f, l)) {} constexpr Iterator begin() const noexcept { return first; } constexpr Iterator end() const noexcept { return last; } }; constexpr Range rep(const int l, const int r) noexcept { return Range(l, r); } constexpr Range rep(const int n) noexcept { return Range(0, n); } #line 2 "library2/utility/setmax.hpp" template <typename T> bool setmax(T &lhs, const T &rhs) { if (lhs < rhs) { lhs = rhs; return true; } return false; } #line 2 "library2/utility/setmin.hpp" template <typename T> bool setmin(T& lhs, const T& rhs) { if (lhs > rhs) { lhs = rhs; return true; } return false; } #line 9 "paper.cpp" #include "race.h" int N; int K; struct Edge { int to; int cost; }; std::vector<std::vector<Edge>> Tree; struct DpData { std::map<int, int> d; int adj; int depth; // real key : d.key + adj // real value : depth - d.value int size() const { return len(d); } }; void merge(DpData &a, DpData &b) { assert(a.size() >= b.size()); for (const auto &[key, value] : b.d) { const int r = key + b.adj - a.adj; if (a.d.find(r) == a.d.end()) { a.d[r] = a.depth - (b.depth - value); } else { setmax(a.d[r], a.depth - (b.depth - value)); } } } int calc_dp() { int answer = infty<int>; auto dfs = rec_lambda([&](auto &&f, const int v, const int p) -> DpData { if (v != 0 and len(Tree[v]) == 1) { DpData ret; ret.adj = 0; ret.depth = 0; ret.d[0] = 0; return ret; } const int c = len(Tree[v]); std::vector<DpData> children(c); auto collect = [&]() { int count = 0; for (const auto [to, cost] : Tree[v]) { if (to == p) { children[count].adj = -1; } else { children[count] = f(to, v); children[count].adj += cost; ++children[count].depth; } ++count; } int base = (int)(std::max_element(children.begin(), children.end(), [](const DpData &a, const DpData &b) { return a.size() < b.size(); }) - children.begin()); return base; }; int base = collect(); for (const int i : rep(c)) { if (i == base) { continue; } if (children[i].adj == -1) { continue; } for (const auto &[key, value] : children[i].d) { const int r = K - (key + children[i].adj + children[base].adj); if (children[base].d.find(r) != children[base].d.end()) { setmin(answer, (children[i].depth - value) + (children[base].depth - children[base].d[r])); } } merge(children[base], children[i]); } children[base].d[-children[base].adj] = children[base].depth; const int r = K - children[base].adj; if (children[base].d.find(r) != children[base].d.end()) { setmin(answer, children[base].depth - children[base].d[r]); } return std::move(children[base]); }); dfs(0, N); return answer == infty<int> ? -1 : answer; } int best_path(int n, int k, int H[][2], int L[]) { N = n; K = k; Tree.resize(N); for (const int i : rep(N - 1)) { Tree[H[i][0]].push_back({H[i][1], L[i]}); Tree[H[i][1]].push_back({H[i][0], L[i]}); } return calc_dp(); } /* int main() { int n, k; std::cin >> n >> k; int H[20][2]; int L[20]; for (const int i : rep(n - 1)) { int a, b, l; std::cin >> a >> b >> l; H[i][0] = a, H[i][1] = b; L[i] = l; } std::cout << best_path(n, k, H, L) << std::endl; } */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...