#include <iostream> #include <cstdint> #include <unordered_map> #include <unordered_set> #include <deque> #include <utility> #include <optional> struct InputData { unsigned n; std::unordered_map<unsigned, std::unordered_set<unsigned>> graph; std::optional<std::pair<unsigned, unsigned>> teleport; } input_data; void parse_input() { std::cin >> input_data.n; for (unsigned i = 0; i < input_data.n; i++) { std::string line; std::cin >> line; for (unsigned j = 0; j < input_data.n; ++j) { unsigned connects = line[j] - '0'; if (connects) input_data.graph[i].insert(j); } } } struct BfsData { unsigned point; unsigned dist; }; BfsData bfs_max_dist(const unsigned node) { BfsData res{node, 0}; std::deque<BfsData> q{res}; std::unordered_set<unsigned> seen; while (!q.empty()) { BfsData node_data = q.front(); // std::cerr << "node_data: " << node_data.point << ' ' << node_data.dist << '\n'; q.pop_front(); if (seen.contains(node_data.point)) continue; if (node_data.dist > res.dist) res = node_data; seen.insert(node_data.point); for (const auto elem : input_data.graph[node_data.point]) { q.emplace_back(elem, node_data.dist+1); } if (!input_data.teleport.has_value()) continue; if (node_data.point == input_data.teleport->first) { q.emplace_back(input_data.teleport->second, node_data.dist); } else if (node_data.point == input_data.teleport->second) { q.emplace_back(input_data.teleport->first, node_data.dist); } } return res; } unsigned get_diameter() { const auto first = bfs_max_dist(0); const auto second = bfs_max_dist(first.point); return second.dist; } unsigned brute_force() { std::optional<unsigned> res = std::nullopt; for (unsigned i = 0; i < input_data.n-1; ++i) { for (unsigned j = i+1; j < input_data.n; ++j) { input_data.teleport = {i, j}; const auto result = get_diameter(); if (!res.has_value() || result < res.value()) res = result; } } return res.value_or(2137); } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); unsigned t; std::cin >> t; for (unsigned i = 0; i < t; ++i) { input_data = { 0 }; parse_input(); const auto res = brute_force(); std::cout << res << '\n'; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #include <iostream> #include <cstdint> #include <unordered_map> #include <unordered_set> #include <deque> #include <utility> #include <optional> struct InputData { unsigned n; std::unordered_map<unsigned, std::unordered_set<unsigned>> graph; std::optional<std::pair<unsigned, unsigned>> teleport; } input_data; void parse_input() { std::cin >> input_data.n; for (unsigned i = 0; i < input_data.n; i++) { std::string line; std::cin >> line; for (unsigned j = 0; j < input_data.n; ++j) { unsigned connects = line[j] - '0'; if (connects) input_data.graph[i].insert(j); } } } struct BfsData { unsigned point; unsigned dist; }; BfsData bfs_max_dist(const unsigned node) { BfsData res{node, 0}; std::deque<BfsData> q{res}; std::unordered_set<unsigned> seen; while (!q.empty()) { BfsData node_data = q.front(); // std::cerr << "node_data: " << node_data.point << ' ' << node_data.dist << '\n'; q.pop_front(); if (seen.contains(node_data.point)) continue; if (node_data.dist > res.dist) res = node_data; seen.insert(node_data.point); for (const auto elem : input_data.graph[node_data.point]) { q.emplace_back(elem, node_data.dist+1); } if (!input_data.teleport.has_value()) continue; if (node_data.point == input_data.teleport->first) { q.emplace_back(input_data.teleport->second, node_data.dist); } else if (node_data.point == input_data.teleport->second) { q.emplace_back(input_data.teleport->first, node_data.dist); } } return res; } unsigned get_diameter() { const auto first = bfs_max_dist(0); const auto second = bfs_max_dist(first.point); return second.dist; } unsigned brute_force() { std::optional<unsigned> res = std::nullopt; for (unsigned i = 0; i < input_data.n-1; ++i) { for (unsigned j = i+1; j < input_data.n; ++j) { input_data.teleport = {i, j}; const auto result = get_diameter(); if (!res.has_value() || result < res.value()) res = result; } } return res.value_or(2137); } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); unsigned t; std::cin >> t; for (unsigned i = 0; i < t; ++i) { input_data = { 0 }; parse_input(); const auto res = brute_force(); std::cout << res << '\n'; } return 0; } |