This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub noshi91/Library
#define PROBLEM \ "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A&lang=ja" #include "data_structure/erasable_heap.cpp" #include "data_structure/pairing_heap.cpp" #include "other/less_equal_ordered_set.cpp" #include <iostream> #include <limits> #include <utility> #include <vector> int main() { #include "other/fast_ios.cpp" int n, m, r; std::cin >> n >> m >> r; std::vector<std::vector<std::pair<int, int>>> g(n); for (int i = 0; i != m; i += 1) { int s, t, d; std::cin >> s >> t >> d; g[s].emplace_back(d, t); } constexpr int Inf = std::numeric_limits<int>::max(); std::vector<int> dist(n, Inf); dist[r] = 0; erasable_heap<pairing_heap<less_equal_ordered_set<std::pair<int, int>>>> heap; heap.push({0, r}); while (!heap.empty()) { const auto [c, v] = heap.top(); heap.pop(); for (const auto &[d, u] : g[v]) { if (c + d < dist[u]) { if (dist[u] != Inf) heap.erase({dist[u], u}); dist[u] = c + d; heap.push({dist[u], u}); } } } for (int i = 0; i != n; i += 1) { if (dist[i] < Inf) std::cout << dist[i]; else std::cout << "INF"; std::cout << "\n"; } }
#line 1 "test/erasable_heap.test.cpp" #define PROBLEM \ "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A&lang=ja" #line 1 "data_structure/erasable_heap.cpp" #include <cassert> #include <utility> template <class Heap> class erasable_heap { using W = typename Heap::value_compare; using T = typename Heap::value_type; public: using value_compare = W; using value_type = T; private: static bool equivalent(const T &x, const T &y) { return W::compare(x, y) && W::compare(y, x); } Heap base; Heap erased; void normalize() { while (!base.empty() && !erased.empty() && equivalent(base.top(), erased.top())) { base.pop(); erased.pop(); } } public: erasable_heap() = default; bool empty() const { return base.empty(); } const T &top() const { assert(!empty()); return base.top(); } void push(T x) { base.push(std::move(x)); normalize(); } T pop() { assert(!empty()); T ret = base.pop(); normalize(); return ret; } void erase(T x) { erased.push(std::move(x)); normalize(); } }; /** * @brief Erasable Heap */ #line 2 "data_structure/pairing_heap.cpp" #include <memory> #line 4 "data_structure/pairing_heap.cpp" template <class W> class pairing_heap { using Self = pairing_heap; using T = typename W::value_type; public: using value_compare = W; using value_type = T; private: class node_type; using node_ptr = std::unique_ptr<node_type>; class node_type { public: T value; node_ptr head; node_ptr next; node_type(T value) : value(std::move(value)), head(), next() {} }; static node_ptr merge(node_ptr x, node_ptr y) { if (!x) return y; if (!y) return x; if (!W::compare(x->value, y->value)) std::swap(x, y); y->next = std::move(x->head); x->head = std::move(y); return x; } static node_ptr merge_list(node_ptr list) { if (!list || !list->next) return list; node_ptr next = std::move(list->next); node_ptr rem = std::move(next->next); return merge(merge(std::move(list), std::move(next)), merge_list(std::move(rem))); } node_ptr root; pairing_heap(node_ptr root) : root(std::move(root)) {} public: pairing_heap() = default; bool empty() const { return !root; } const T &top() const { assert(!empty()); return root->value; } void push(T x) { root = merge(std::move(root), std::make_unique<node_type>(std::move(x))); } T pop() { assert(!empty()); T ret = std::move(root->value); root = merge_list(std::move(root->head)); return ret; } static Self meld(Self x, Self y) { return Self(merge(std::move(x.root), std::move(y.root))); } }; /** * @brief Pairing Heap */ #line 1 "other/less_equal_ordered_set.cpp" template <class T> class less_equal_ordered_set { public: using value_type = T; static constexpr bool compare(const T &x, const T &y) noexcept { return x <= y; } }; #line 7 "test/erasable_heap.test.cpp" #include <iostream> #include <limits> #line 11 "test/erasable_heap.test.cpp" #include <vector> int main() { #line 1 "other/fast_ios.cpp" std::ios::sync_with_stdio(false); std::cin.tie(nullptr); #line 15 "test/erasable_heap.test.cpp" int n, m, r; std::cin >> n >> m >> r; std::vector<std::vector<std::pair<int, int>>> g(n); for (int i = 0; i != m; i += 1) { int s, t, d; std::cin >> s >> t >> d; g[s].emplace_back(d, t); } constexpr int Inf = std::numeric_limits<int>::max(); std::vector<int> dist(n, Inf); dist[r] = 0; erasable_heap<pairing_heap<less_equal_ordered_set<std::pair<int, int>>>> heap; heap.push({0, r}); while (!heap.empty()) { const auto [c, v] = heap.top(); heap.pop(); for (const auto &[d, u] : g[v]) { if (c + d < dist[u]) { if (dist[u] != Inf) heap.erase({dist[u], u}); dist[u] = c + d; heap.push({dist[u], u}); } } } for (int i = 0; i != n; i += 1) { if (dist[i] < Inf) std::cout << dist[i]; else std::cout << "INF"; std::cout << "\n"; } }