#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; } |
English