#include "Util/Debug/graph-debug.hpp"
#pragma once #include <iostream> #include <iomanip> #include "../../Graph/graph-template.hpp" #include "./debug.hpp" /** * @brief graph-debug (グラフのデバッグ出力) */ template <class T> std::ostream& operator<<(std::ostream& os, const Edge<T>& e) { os << std::setw(0) << '(' << std::setfill('0') << std::setw(2) << e.from << "-" << std::setw(2) << e.to << ", w=" << std::setw(2) << e.weight; if (e.id != -1) os << ", id=" << std::setw(2) << e.id; os << std::setfill(' ') << ')'; return os; } template<> std::ostream& operator<<(std::ostream& os, const Edge<void>& e) { os << std::setw(0) << '(' << std::setfill('0') << std::setw(2) << e.from << "-" << std::setw(2) << e.to; if (e.id != -1) os << ", id=" << std::setw(2) << e.id; os << std::setfill(' ') << ')'; return os; }
#line 2 "Util/Debug/graph-debug.hpp" #include <iostream> #include <iomanip> #line 2 "Graph/graph-template.hpp" #include <cstdint> #include <vector> #line 5 "Graph/graph-template.hpp" /** * @brief graph-template (Edge, Graph, MatrixGraph) */ //! グラフの辺 (重み付き) template <class T> struct Edge { int from, to; T weight; int id; Edge() = default; constexpr explicit Edge(int to_, const T& weight_) : Edge(-1, to_, weight_, -1) {} constexpr Edge(int from_, int to_, const T& weight_, int id_ = -1) : from(from_) , to(to_) , weight(weight_) , id(id_) {} constexpr const Edge rev() const { return Edge(to, from, weight, id); } template <class Int, std::enable_if_t<std::is_integral<Int>::value, std::nullptr_t> = nullptr> constexpr operator Int() const { return static_cast<Int>(to); } friend std::istream& operator>>(std::istream& is, Edge& e) { return is >> e.from >> e.to >> e.weight; } }; //! グラフの辺 (重みなし) template <> struct Edge<void> { int from, to; int id; Edge() = default; constexpr explicit Edge(int to_) : Edge(-1, to_, -1) {} constexpr Edge(int from_, int to_, int id_ = -1) : from(from_) , to(to_) , id(id_) {} constexpr const Edge rev() const { return Edge(to, from, id); } template <class Int, std::enable_if_t<std::is_integral<Int>::value, std::nullptr_t> = nullptr> constexpr operator Int() const { return static_cast<Int>(to); } friend std::istream& operator>>(std::istream& is, Edge& e) { return is >> e.from >> e.to; } }; template <class T> using Graph = std::vector<std::vector<Edge<T>>>; #line 5 "Util/Debug/debug.hpp" #line 3 "Util/int-infinity.hpp" /** * @brief int-infinity (整数のデカイ値) * 2倍してもオーバーフローしない & memset()にも使える (需要ある?) */ constexpr int32_t INF = 0x3f3f3f3f; constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL; #line 7 "Util/Debug/debug.hpp" /** * @brief Debug */ #ifdef LOCAL_DEBUG namespace dbg { int w_ = 4; bool negativeValAsNull_ = true; std::ostream* os = &std::cerr; template <class T, std::enable_if_t<!std::is_arithmetic<T>::value, std::nullptr_t> = nullptr> void put(const T& x) { *os << std::setw(w_) << x; } template <class T, std::enable_if_t<std::is_signed<T>::value, std::nullptr_t> = nullptr> void put(const T& x) { if (x <= -INF) *os << std::setw(w_) << "-INF"; else if (negativeValAsNull_ && x < 0) *os << std::setw(w_) << " - "; else if (x >= INF) *os << std::setw(w_) << "INF"; else *os << std::setw(w_) << x; } template <class T, std::enable_if_t<std::is_unsigned<T>::value, std::nullptr_t> = nullptr> void put(const T& x) { if (static_cast<int64_t>(x) >= static_cast<int64_t>(INF)) *os << std::setw(w_) << "INF"; else *os << std::setw(w_) << x; } template <class A, class B> void put(const std::pair<A, B>& t) { *os << '(' << std::setw(w_) << std::get<0>(t) << ", " << std::setw(w_) << std::get<1>(t) << ')'; } template <class A, class B, class C> void put(const std::tuple<A, B, C>& t) { *os << '(' << std::setw(w_) << std::get<0>(t) << ", " << std::setw(w_) << std::get<1>(t) << ", " << std::setw(w_) << std::get<2>(t) << ')'; } template <class Arr> void showArrayH__(const Arr& a, size_t begin, size_t end) { for (size_t i = begin; i < end; ++i) *os << '[' << std::setw(dbg::w_) << i << "] "; *os << '\n'; for (size_t i = begin; i < end; ++i) *os << ' ', dbg::put(a[i]), *os << " "; *os << '\n'; } template <class Arr> void showArrayV__(const Arr& a, size_t begin, size_t end) { for (size_t i = begin; i < end; ++i) *os << '[' << std::setw(2) << i << ']', dbg::put(a[i]), *os << "\n"; *os << std::flush; } template <class Table> void showTable__(const Table& t, size_t yBegin, size_t yEnd, size_t xBegin, size_t xEnd) { *os << std::string(1 + 2 + 1, ' '); for (size_t j = xBegin; j < xEnd; ++j) *os << '[' << std::setw(dbg::w_) << j << "] "; *os << '\n'; for (size_t i = yBegin; i < yEnd; ++i) { *os << '[' << std::setw(2) << i << "]"; for (size_t j = xBegin; j < xEnd; ++j) *os << ' ', dbg::put(t[i][j]), *os << " "; *os << '\n'; } } } // namespace dbg void debug_setw(int w) { dbg::w_ = w; } void debug_negativeValAsNull(bool f) { dbg::negativeValAsNull_ = f; } void debug_setOstream(std::ostream& os) { dbg::os = &os; } void debug_hr() { *dbg::os << "----------------------------------------------------------------------\n"; } void debug_println() { *dbg::os << std::endl; } template <class Head, class... Tail> void debug_println(const Head& head, const Tail&... tail) { dbg::put(head); debug_println(tail...); } #define putDbgPrefix() *dbg::os << __func__ << '(' << std::setfill('0') << std::setw(3) << __LINE__ << std::setfill(' ') << "): " #define showArrayH(a, beginIdx, endIdx) (void)(putDbgPrefix() << #a << ":\n"), dbg::showArrayH__(a, beginIdx, endIdx) #define showArrayV(a, beginIdx, endIdx) (void)(putDbgPrefix() << #a << ":\n"), dbg::showArrayV__(a, beginIdx, endIdx) #define showTable(t, yBegin, yEnd, xBegin, xEnd) (void)(putDbgPrefix() << #t << ":\n"), dbg::showTable__(t, yBegin, yEnd, xBegin, xEnd) #define dbgMsg_(x) " | " #x " = ", x #define dump1(a) (void)(putDbgPrefix()), debug_println(#a " = ", a) #define dump2(a, b) (void)(putDbgPrefix()), debug_println(#a " = ", a, dbgMsg_(b)) #define dump3(a, b, c) (void)(putDbgPrefix()), debug_println(#a " = ", a, dbgMsg_(b), dbgMsg_(c)) #define dump4(a, b, c, d) (void)(putDbgPrefix()), debug_println(#a " = ", a, dbgMsg_(b), dbgMsg_(c), dbgMsg_(d)) #define dump5(a, b, c, d, e) (void)(putDbgPrefix()), debug_println(#a " = ", a, dbgMsg_(b), dbgMsg_(c), dbgMsg_(d), dbgMsg_(e)) #define dump6(a, b, c, d, e, f) (void)(putDbgPrefix()), debug_println(#a " = ", a, dbgMsg_(b), dbgMsg_(c), dbgMsg_(d), dbgMsg_(e), dbgMsg_(f)) #define dump7(a, b, c, d, e, f, g) (void)(putDbgPrefix()), debug_println(#a " = ", a, dbgMsg_(b), dbgMsg_(c), dbgMsg_(d), dbgMsg_(e), dbgMsg_(f), dbgMsg_(g)) #define GET_8TH_ARG(dummy1, dummy2, dummy3, dummy4, dummy5, dummy6, dumy7, NAME, ...) NAME #define dump(...) GET_8TH_ARG(__VA_ARGS__, dump7, dump6, dump5, dump4, dump3, dump2, dump1)(__VA_ARGS__) #else #define debug_setw(...) ((void)0) #define debug_negativeValAsNull(...) ((void)0) #define debug_setOstream(...) ((void)0) #define debug_hr(...) ((void)0) #define debug_println(...) ((void)0) #define showArrayH(...) ((void)0) #define showArrayV(...) ((void)0) #define showTable(...) ((void)0) #define dump(...) ((void)0) #endif #line 7 "Util/Debug/graph-debug.hpp" /** * @brief graph-debug (グラフのデバッグ出力) */ template <class T> std::ostream& operator<<(std::ostream& os, const Edge<T>& e) { os << std::setw(0) << '(' << std::setfill('0') << std::setw(2) << e.from << "-" << std::setw(2) << e.to << ", w=" << std::setw(2) << e.weight; if (e.id != -1) os << ", id=" << std::setw(2) << e.id; os << std::setfill(' ') << ')'; return os; } template<> std::ostream& operator<<(std::ostream& os, const Edge<void>& e) { os << std::setw(0) << '(' << std::setfill('0') << std::setw(2) << e.from << "-" << std::setw(2) << e.to; if (e.id != -1) os << ", id=" << std::setw(2) << e.id; os << std::setfill(' ') << ')'; return os; }