Advertisement
Guest User

Поиск центра дерева

a guest
Nov 13th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.30 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <tuple>
  4. #include <queue>
  5. #include <algorithm>
  6.  
  7. class Graph {
  8. public:
  9.     explicit Graph(size_t vertex_count)
  10.         : adjacency_matrix_(vertex_count),
  11.           vertex_colors_(vertex_count),
  12.           vertex_degrees_(vertex_count),
  13.           vertex_types_(vertex_count),
  14.           vertex_children_types_(vertex_count),
  15.           vertex_levels_(vertex_count),
  16.           vertices_on_levels_(1) {}
  17.  
  18.     void AddEdge(size_t vertex_from, size_t vertex_to) {
  19.         adjacency_matrix_[vertex_from].push_back(vertex_to);
  20.         adjacency_matrix_[vertex_to].push_back(vertex_from);
  21.         ++vertex_degrees_[vertex_from];
  22.         ++vertex_degrees_[vertex_to];
  23.     }
  24.  
  25.     void LevelizeTree() {
  26.         auto leaves = GetLeaves(0);
  27.         std::vector<int> degrees{vertex_degrees_};
  28.         std::queue<size_t> leaves_queue;
  29.         size_t vertices_looked = 0;
  30.         for (size_t vertex_index = 0; vertex_index < std::size(leaves); ++vertex_index) {
  31.             leaves_queue.push(leaves[vertex_index]);
  32.             ++vertices_looked;
  33.             vertices_on_levels_[0].push_back(leaves[vertex_index]);
  34.         }
  35.  
  36.         while (vertices_looked < std::size(adjacency_matrix_)) {
  37.             vertices_on_levels_.emplace_back();
  38.             size_t current_level = vertex_levels_[leaves_queue.front()];
  39.             size_t next_level = current_level + 1;
  40.             do {
  41.                 auto vertex = leaves_queue.front();
  42.                 leaves_queue.pop();
  43.                 auto adjacent = adjacency_matrix_[vertex];
  44.                 for (const auto &adjacent_vertex : adjacent) {
  45.                     if (!vertex_colors_[adjacent_vertex]) {
  46.                         --degrees[adjacent_vertex];
  47.                         if (degrees[adjacent_vertex] == 1) {
  48.                             leaves_queue.push(adjacent_vertex);
  49.                             ++vertices_looked;
  50.                             vertex_colors_[vertex] = true;
  51.                             vertex_levels_[adjacent_vertex] = next_level;
  52.                             vertices_on_levels_[next_level].push_back(adjacent_vertex);
  53.                         }
  54.                     }
  55.                 }
  56.             } while (vertex_levels_[leaves_queue.front()] == current_level);
  57.         }
  58.         if (std::size(leaves_queue) == 2) {
  59.             std::vector<size_t> new_root_adjacent_list(2);
  60.             auto first_center_vertex = leaves_queue.front();
  61.             new_root_adjacent_list.push_back(first_center_vertex);
  62.             leaves_queue.pop();
  63.             auto second_center_vertex = leaves_queue.front();
  64.             new_root_adjacent_list.push_back(second_center_vertex);
  65.             adjacency_matrix_.push_back(std::move(new_root_adjacent_list));
  66.             vertex_degrees_.push_back(2);
  67.             size_t new_level = vertex_levels_[first_center_vertex] + 1;
  68.             vertex_levels_.push_back(new_level);
  69.             vertices_on_levels_.push_back({std::size(adjacency_matrix_) - 1});
  70.         }
  71.         vertex_colors_.clear();
  72.         vertex_colors_.resize(std::size(adjacency_matrix_));
  73.     }
  74.  
  75. private:
  76.     std::vector<std::vector<size_t>> adjacency_matrix_;
  77.     std::vector<bool> vertex_colors_;
  78.     std::vector<int> vertex_degrees_;
  79.     std::vector<size_t> vertex_types_;
  80.     std::vector<std::vector<size_t>> vertex_children_types_;
  81.     std::vector<size_t> vertex_levels_;
  82.     std::vector<std::vector<size_t>> vertices_on_levels_;
  83.  
  84.     std::vector<size_t> GetLeaves(size_t level) {
  85.         std::vector<size_t> leaves;
  86.  
  87.         if (level == 0) {
  88.             for (size_t vertex_index = 0;
  89.                  vertex_index < std::size(vertex_degrees_);
  90.                  ++vertex_index) {
  91.                 if (vertex_degrees_[vertex_index] <= 1) {
  92.                     leaves.push_back(vertex_index);
  93.                 }
  94.             }
  95.         } else {
  96.             for (const auto &vertex : vertices_on_levels_[level]) {
  97.                 if (vertex_degrees_[vertex] <= 1) {
  98.                     leaves.push_back(vertex);
  99.                 }
  100.             }
  101.         }
  102.  
  103.         return leaves;
  104.     }
  105. };
  106.  
  107. int main() {
  108.     std::ios_base::sync_with_stdio(false);
  109.     std::cin.tie(nullptr);
  110.  
  111.     size_t cities_count = 0;
  112.     std::cin >> cities_count;
  113.  
  114.     Graph old_graph(cities_count);
  115.     for (size_t i = 0; i < cities_count - 1; ++i) {
  116.         size_t city_from = 0;
  117.         size_t city_to = 0;
  118.         std::cin >> city_from;
  119.         std::cin >> city_to;
  120.         old_graph.AddEdge(city_from - 1, city_to - 1);
  121.     }
  122.  
  123. //    Graph new_graph(cities_count);
  124. //    for (size_t i = 0; i < cities_count - 1; ++i) {
  125. //        size_t city_from = 0;
  126. //        size_t city_to = 0;
  127. //        std::cin >> city_from;
  128. //        std::cin >> city_to;
  129. //        new_graph.AddEdge(city_from - 1, city_to - 1);
  130. //    }
  131.  
  132.     old_graph.LevelizeTree();
  133. //    new_graph.LevelizeTree();
  134.  
  135.  
  136. //    auto [old_graph_center_vertex, old_graph_center_type] = old_graph.GetTypeOfCenterVertex();
  137. //    auto [new_graph_center_vertex, new_graph_center_type] = new_graph.GetTypeOfCenterVertex();
  138. //    if (old_graph_center_type == new_graph_center_type) {
  139. //        std::cout << "TODO, center is " << old_graph_center_vertex << " and " << new_graph_center_vertex << "\n";
  140. //    } else {
  141. //        std::cout << -1 << "\n";
  142. //    }
  143.  
  144.     return 0;
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement