Advertisement
Guest User

Untitled

a guest
Oct 16th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <map>
  6. #include <set>
  7.  
  8. double dist(std::pair<int, int> x, std::pair<int, int> y) {
  9. return std::pow(std::pow(x.first - y.first, 2) + std::pow(x.second - y.second, 2), 0.5);
  10. }
  11.  
  12. int DSU_get(int node, std::vector<int>& trees) {
  13. return (node == trees[node]) ? node : (trees[node] = DSU_get(trees[node], trees));
  14. }
  15.  
  16. void DSU_unite(int node1, int node2, std::vector<int>& trees) {
  17. node1 = DSU_get(node1, trees);
  18. node2 = DSU_get(node2, trees);
  19. if (rand() & 1) {
  20. std::swap(node1, node2);
  21. }
  22. if (node1 != node2) {
  23. trees[node1] = node2;
  24. }
  25. }
  26.  
  27. std::pair<int, int> step(int x_min, int x_max, int y_min, int y_max) {
  28. int step_x = 0, step_y = 0;
  29. if (x_max - x_min <= 50) {
  30. step_x = 1;
  31. } else if (x_max - x_min <= 100) {
  32. step_x = 2;
  33. } else if (x_max - x_min <= 300) {
  34. step_x = 5;
  35. } else if (x_max - x_min <= 500) {
  36. step_x = 10;
  37. } else if (x_max - x_min <= 1000) {
  38. step_x = 20;
  39. } else if (x_max - x_min <= 2000) {
  40. step_x = 40;
  41. } else if (x_max - x_min <= 5000) {
  42. step_x = 80;
  43. } else {
  44. step_x = 150;
  45. }
  46. if (y_max - y_min <= 50) {
  47. step_y = 1;
  48. } else if (y_max - y_min <= 100) {
  49. step_y = 2;
  50. } else if (y_max - y_min <= 300) {
  51. step_y = 5;
  52. } else if (y_max - y_min <= 500) {
  53. step_y = 10;
  54. } else if (y_max - y_min <= 1000) {
  55. step_y = 20;
  56. } else if (y_max - y_min <= 2000) {
  57. step_y = 40;
  58. } else if (y_max - y_min <= 5000) {
  59. step_y = 80;
  60. } else {
  61. step_y = 150;
  62. }
  63. return (std::make_pair(step_x, step_y));
  64. }
  65.  
  66. double Cruscal(int count_node, std::vector<std::pair<double, std::pair<int, int>>>& graph) {
  67. std::vector<int> trees(count_node);
  68. for (int i = 0; i != count_node; ++i) {
  69. trees[i] = i;
  70. }
  71. int node1, node2;
  72. double result_weight = 0.0, weight;
  73. std::sort(graph.begin(), graph.end());
  74. for (size_t i = 0; i != graph.size(); ++i) {
  75. node1 = graph[i].second.first;
  76. node2 = graph[i].second.second;
  77. weight = graph[i].first;
  78. if (DSU_get(node1, trees) != DSU_get(node2, trees)) {
  79. result_weight += weight;
  80. DSU_unite(node1, node2, trees);
  81. }
  82. }
  83. return result_weight;
  84. }
  85.  
  86. int main() {
  87. int count_town, count_rout, x, y;
  88. std::cin >> count_town >> count_rout;
  89. std::map<std::pair<int ,int>, int> code;
  90. std::vector<std::pair<int, int>> nodes;
  91. std::set<std::pair<int ,int>> nodes_set;
  92. std::pair<int, int> par;
  93. int x_min = 100000, x_max = 0, y_min = 100000, y_max = 0;
  94. for (int i = 0; i != count_town; ++i) {
  95. std::cin >> x >> y;
  96. if (x > x_max) {
  97. x_max = x;
  98. }
  99. if (x < x_min) {
  100. x_min = x;
  101. }
  102. if (y > y_max) {
  103. y_max = y;
  104. }
  105. if (y < y_min) {
  106. y_min = y;
  107. }
  108. par = std::make_pair(x, y);
  109. nodes.push_back(par);
  110. nodes_set.insert(par);
  111. code[par] = i;
  112. }
  113.  
  114. std::pair<int, int> steps = step(x_min, x_max, y_min, y_max);
  115.  
  116. std::vector<std::pair<double, std::pair<int, int>>> graph, graph_cur;
  117.  
  118. for (size_t i = 0; i != nodes.size(); ++i) {
  119. for (size_t j = i + 1; j != nodes.size(); ++j) {
  120. graph.push_back(std::make_pair(dist(nodes[i], nodes[j]),
  121. std::make_pair(code[nodes[i]], code[nodes[j]])));
  122. }
  123. }
  124.  
  125. double cur_val = 0;
  126. std::pair<int ,int> best;
  127. std::set<std::pair<int, int>> solve;
  128. double min_weight = Cruscal(count_town, graph), min_weight_cur = min_weight;
  129. for (size_t z = 0; z != count_rout; ++z) {
  130. for (int i = x_min; i != x_max + 1; i += steps.first) {
  131. for (int j = y_min; j != y_max + 1; j += steps.second) {
  132. if (nodes_set.find(std::make_pair(i, j)) == nodes_set.end()) {
  133. graph_cur = graph;
  134. par = std::make_pair(i, j);
  135. for (size_t k = 0; k != count_town; ++k) {
  136. graph_cur.push_back(std::make_pair(dist(nodes[k], par),
  137. std::make_pair(code[nodes[k]], count_town)));
  138. }
  139. cur_val = Cruscal(count_town + 1, graph_cur);
  140. if (cur_val < min_weight_cur) {
  141. min_weight_cur = cur_val;
  142. best = par;
  143. }
  144. }
  145. }
  146. }
  147. if (min_weight != min_weight_cur) {
  148. min_weight = min_weight_cur;
  149. for (size_t k = 0; k != count_town; ++k) {
  150. graph.push_back(std::make_pair(dist(nodes[k], best),
  151. std::make_pair(code[nodes[k]], count_town)));
  152. }
  153. ++count_town;
  154. solve.insert(best);
  155. nodes.push_back(best);
  156. nodes_set.insert(best);
  157. } else {
  158. break;
  159. }
  160. }
  161. std::cout << solve.size() << std::endl;
  162. for (auto x : solve) {
  163. std::cout << x.first << " " << x.second << std::endl;
  164. }
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement