Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <tuple>
- #include <queue>
- #include <algorithm>
- class Graph {
- public:
- explicit Graph(size_t vertex_count)
- : adjacency_matrix_(vertex_count),
- vertex_colors_(vertex_count),
- vertex_degrees_(vertex_count),
- vertex_types_(vertex_count),
- vertex_children_types_(vertex_count),
- vertex_levels_(vertex_count),
- vertices_on_levels_(1) {}
- void AddEdge(size_t vertex_from, size_t vertex_to) {
- adjacency_matrix_[vertex_from].push_back(vertex_to);
- adjacency_matrix_[vertex_to].push_back(vertex_from);
- ++vertex_degrees_[vertex_from];
- ++vertex_degrees_[vertex_to];
- }
- void LevelizeTree() {
- auto leaves = GetLeaves(0);
- std::vector<int> degrees{vertex_degrees_};
- std::queue<size_t> leaves_queue;
- size_t vertices_looked = 0;
- for (size_t vertex_index = 0; vertex_index < std::size(leaves); ++vertex_index) {
- leaves_queue.push(leaves[vertex_index]);
- ++vertices_looked;
- vertices_on_levels_[0].push_back(leaves[vertex_index]);
- }
- while (vertices_looked < std::size(adjacency_matrix_)) {
- vertices_on_levels_.emplace_back();
- size_t current_level = vertex_levels_[leaves_queue.front()];
- size_t next_level = current_level + 1;
- do {
- auto vertex = leaves_queue.front();
- leaves_queue.pop();
- auto adjacent = adjacency_matrix_[vertex];
- for (const auto &adjacent_vertex : adjacent) {
- if (!vertex_colors_[adjacent_vertex]) {
- --degrees[adjacent_vertex];
- if (degrees[adjacent_vertex] == 1) {
- leaves_queue.push(adjacent_vertex);
- ++vertices_looked;
- vertex_colors_[vertex] = true;
- vertex_levels_[adjacent_vertex] = next_level;
- vertices_on_levels_[next_level].push_back(adjacent_vertex);
- }
- }
- }
- } while (vertex_levels_[leaves_queue.front()] == current_level);
- }
- if (std::size(leaves_queue) == 2) {
- std::vector<size_t> new_root_adjacent_list(2);
- auto first_center_vertex = leaves_queue.front();
- new_root_adjacent_list.push_back(first_center_vertex);
- leaves_queue.pop();
- auto second_center_vertex = leaves_queue.front();
- new_root_adjacent_list.push_back(second_center_vertex);
- adjacency_matrix_.push_back(std::move(new_root_adjacent_list));
- vertex_degrees_.push_back(2);
- size_t new_level = vertex_levels_[first_center_vertex] + 1;
- vertex_levels_.push_back(new_level);
- vertices_on_levels_.push_back({std::size(adjacency_matrix_) - 1});
- }
- vertex_colors_.clear();
- vertex_colors_.resize(std::size(adjacency_matrix_));
- }
- private:
- std::vector<std::vector<size_t>> adjacency_matrix_;
- std::vector<bool> vertex_colors_;
- std::vector<int> vertex_degrees_;
- std::vector<size_t> vertex_types_;
- std::vector<std::vector<size_t>> vertex_children_types_;
- std::vector<size_t> vertex_levels_;
- std::vector<std::vector<size_t>> vertices_on_levels_;
- std::vector<size_t> GetLeaves(size_t level) {
- std::vector<size_t> leaves;
- if (level == 0) {
- for (size_t vertex_index = 0;
- vertex_index < std::size(vertex_degrees_);
- ++vertex_index) {
- if (vertex_degrees_[vertex_index] <= 1) {
- leaves.push_back(vertex_index);
- }
- }
- } else {
- for (const auto &vertex : vertices_on_levels_[level]) {
- if (vertex_degrees_[vertex] <= 1) {
- leaves.push_back(vertex);
- }
- }
- }
- return leaves;
- }
- };
- int main() {
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(nullptr);
- size_t cities_count = 0;
- std::cin >> cities_count;
- Graph old_graph(cities_count);
- for (size_t i = 0; i < cities_count - 1; ++i) {
- size_t city_from = 0;
- size_t city_to = 0;
- std::cin >> city_from;
- std::cin >> city_to;
- old_graph.AddEdge(city_from - 1, city_to - 1);
- }
- // Graph new_graph(cities_count);
- // for (size_t i = 0; i < cities_count - 1; ++i) {
- // size_t city_from = 0;
- // size_t city_to = 0;
- // std::cin >> city_from;
- // std::cin >> city_to;
- // new_graph.AddEdge(city_from - 1, city_to - 1);
- // }
- old_graph.LevelizeTree();
- // new_graph.LevelizeTree();
- // auto [old_graph_center_vertex, old_graph_center_type] = old_graph.GetTypeOfCenterVertex();
- // auto [new_graph_center_vertex, new_graph_center_type] = new_graph.GetTypeOfCenterVertex();
- // if (old_graph_center_type == new_graph_center_type) {
- // std::cout << "TODO, center is " << old_graph_center_vertex << " and " << new_graph_center_vertex << "\n";
- // } else {
- // std::cout << -1 << "\n";
- // }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement