Advertisement
Guest User

Untitled

a guest
Mar 20th, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.14 KB | None | 0 0
  1.  
  2. //
  3. // Created by afusikey on 20.03.19.
  4. //
  5. #include <iostream>
  6. #include <vector>
  7. #include <algorithm>
  8. #include <cmath>
  9. #include <iomanip>
  10. #include <stack>
  11.  
  12. using namespace std;
  13. const int INF = 1000000000;
  14.  
  15.  
  16. struct sort_pred {
  17.     bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
  18.         return left.second < right.second;
  19.     }
  20. };
  21.  
  22. double distance(pair<int, int> p1, pair<int, int> p2){
  23.     double dist = sqrt((p1.first - p2.first) *
  24.                        (p1.first - p2.first) +
  25.                        (p1.second - p2.second) *
  26.                        (p1.second - p2.second));
  27.     return dist;
  28. }
  29.  
  30.  
  31. int main() {
  32.     std::ios_base::sync_with_stdio(false), std::cin.tie(nullptr);
  33.  
  34.     int n;
  35.     cin >> n;
  36.  
  37.     auto points = vector<pair<int, int>>(n);
  38.     auto g = vector<vector<double>>(n);
  39.     for (int i = 0; i < n; i ++) {
  40.         g[i] = vector<double>(n);
  41.     }
  42.  
  43.     for (int i = 0; i < n; i ++)
  44.     {
  45.         cin >> points[i].first >> points[i].second;
  46.     }
  47.  
  48.     sort(points.begin(), points.end());
  49.  
  50.     for (int i = 0; i < points.size(); i ++){
  51.         int start = 0;
  52.         int end = points.size() - 1;
  53.  
  54.         if (points.size() > 800) {
  55.             start = i - 250;
  56.             end = i + 250;
  57.  
  58.             if (start < 0) {
  59.                 end -= start;
  60.                 start = 0;
  61.             }
  62.  
  63.             if (end >= points.size()) {
  64.                 start -= end - points.size();
  65.                 end = points.size() - 1;
  66.             }
  67.  
  68.             vector<pair<int, int>> near(500);
  69.             for (int j = 0; j < 500; j ++){
  70.                 near[j] = points[start + j];
  71.             }
  72.             sort(near.begin(), near.end(), sort_pred());
  73.  
  74.  
  75.             for (int j = 0; j <= 40; j ++) {
  76.                 double dist = distance(points[i], near[j]);
  77.                 g[i][j] = dist;
  78.                 g[j][i] = dist;
  79.             }
  80.         } else
  81.         {
  82.             for (int j = start; j <= end; j ++) {
  83.                 double dist = distance(points[i], points[j]);
  84.                 g[i][j] = dist;
  85.                 g[j][i] = dist;
  86.             }
  87.         }
  88.  
  89.     }
  90.  
  91.     double cost = 0;
  92.     vector<bool> used (n);
  93.     vector<double> min_e (n, INF), sel_e (n, -1);
  94.     min_e[0] = 0;
  95.     auto ans = stack<pair<int, int>>();
  96.  
  97.     for (int i = 0; i < n; ++i) {
  98.         int v = -1;
  99.         for (int j = 0; j < n; ++j)
  100.             if (!used[j] && (v == -1 || min_e[j] < min_e[v]))
  101.                 v = j;
  102.         if (min_e[v] == INF) {
  103.             cout << "No MST!";
  104.             exit(0);
  105.         }
  106.  
  107.         used[v] = true;
  108.         if (sel_e[v] != -1){
  109.             cost += min_e[v];
  110.             ans.push({v+1, sel_e[v]+1});
  111.         }
  112.         //cout << v << " " << sel_e[v] << endl;
  113.  
  114.         for (int to=0; to<n; ++to)
  115.             if (g[v][to] < min_e[to]) {
  116.                 min_e[to] = g[v][to];
  117.                 sel_e[to] = v;
  118.             }
  119.     }
  120.  
  121.     cout << setprecision(15)<< fixed << cost << "\n";
  122.     while (!ans.empty()){
  123.         auto e = ans.top();
  124.         ans.pop();
  125.         cout << e.first << " " << e.second << "\n";
  126.     }
  127.     return 0;
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement