#include #include #include #include #include #include #include #include using Weight = unsigned; using Node = std::string; using Edge = std::pair; using Nodes = std::set; using Edges = std::map; struct Graph { void add_edge(std::string const& s) { static const std::regex re("(.+) to (.+) = (\\d+)"); std::smatch m; if (!std::regex_search(s, m, re)) { std::cout << "Failed to match: " << s << "\n"; abort(); } auto n1 = m.str(1); auto n2 = m.str(2); auto w = std::stoul(m.str(3)); auto edge = std::make_pair(n1, n2); auto back_edge = std::make_pair(n2, n1); nodes_.insert(n1); nodes_.insert(n2); weights_.insert({edge, w}); weights_.insert({back_edge, w}); std::cout << n1 << " <-> " << n2 << " weight: " << w << "\n"; } [[nodiscard]] auto solve_tsp() const -> Weight { Weight min_weight = ~0U; visit_all_perms([&min_weight](Weight w) { if (w < min_weight) { std::cout << "\nNew minimum weight: " << w << "\n"; min_weight = w; } }); return min_weight; } [[nodiscard]] auto solve_max_tsp() const -> Weight { Weight max_weight = 0; visit_all_perms([&max_weight](Weight w) { if (w > max_weight) { std::cout << "\nNew maximum weight: " << w << "\n"; max_weight = w; } }); return max_weight; } private: template void visit_all_perms(Fn fn) const { std::vector nodes(nodes_.begin(), nodes_.end()); std::sort(nodes.begin(), nodes.end()); do { Weight current_weight = 0; std::cout << "\r" << nodes[0]; for (std::size_t i = 1; i < nodes.size(); ++i) { std::cout << " <- " << nodes[i] << std::flush; Edge e = std::make_pair(nodes[i - 1], nodes[i]); auto it = weights_.find(e); assert(it != weights_.end()); current_weight += it->second; } std::cout << " " << std::flush; fn(current_weight); } while (std::next_permutation(nodes.begin(), nodes.end())); std::cout << "\n"; } Nodes nodes_; Edges weights_; }; auto main() -> int { Graph g; // Parse the input for (std::string line; std::getline(std::cin, line);) { g.add_edge(line); } auto w = g.solve_tsp(); std::cout << "Minimum weight = " << w << "\n"; w = g.solve_max_tsp(); std::cout << "Maximum weight = " << w << "\n"; return 0; }