Advertisement
tien_noob

Manhattan MST

Nov 13th, 2022
758
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.20 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using std::vector;
  4. using std::pair;
  5. using std::tuple;
  6.  
  7. struct UnionFind {
  8.     vector<int> par;
  9.     UnionFind(const int n) : par(n, -1) {}
  10.     int find(const int u) {
  11.         return par[u] < 0 ? u : par[u] = find(par[u]);
  12.     }
  13.     bool merge(int x, int y) {
  14.         x = find(x);
  15.         y = find(y);
  16.         if (x == y) {
  17.             return false;
  18.         }
  19.         if (par[x] > par[y]) {
  20.             std::swap(x, y);
  21.         }
  22.         par[x] += par[y];
  23.         par[y] = x;
  24.         return true;
  25.     }
  26. };
  27.  
  28. int main() {
  29.     std::ios_base::sync_with_stdio(false);
  30.     std::cin.tie(nullptr);
  31.     int N;
  32.     std::cin >> N;
  33.     vector<int> X(N), Y(N);
  34.     for (int i = 0; i < N; ++i) {
  35.         std::cin >> X[i] >> Y[i];
  36.     }
  37.     vector<tuple<int, int, int>> edge;
  38.     edge.reserve(4 * N);
  39.     vector<int> idx(N);
  40.     std::iota(idx.begin(), idx.end(), 0);
  41.     for (int s = 0; s < 2; ++s) {
  42.         for (int t = 0; t < 2; ++t) {
  43.             std::sort(idx.begin(), idx.end(), [&](const int i, const int j) {
  44.                 return X[i] + Y[i] < X[j] + Y[j];
  45.             });
  46.             std::map<int, int, std::greater<>> map;
  47.             for (const int i : idx) {
  48.                 for (auto itr = map.lower_bound(Y[i]); itr != map.end(); itr = map.erase(itr)) {
  49.                     const int j = itr->second;
  50.                     const int dx = X[i] - X[j];
  51.                     const int dy = Y[i] - Y[j];
  52.                     if (dy > dx) {
  53.                         break;
  54.                     }
  55.                     edge.emplace_back(dx + dy, i, j);
  56.                 }
  57.                 map[Y[i]] = i;
  58.             }
  59.             std::swap(X, Y);
  60.         }
  61.         for (int i = 0; i < N; ++i) {
  62.             X[i] *= -1;
  63.         }
  64.     }
  65.     std::sort(edge.begin(), edge.end());
  66.     UnionFind dsu(N);
  67.     vector<pair<int, int>> used;
  68.     used.reserve(N - 1);
  69.     long long ans = 0;
  70.     for (const auto& [c, i, j] : edge) {
  71.         if (dsu.merge(i, j)) {
  72.             ans += c;
  73.             used.emplace_back(i, j);
  74.         }
  75.     }
  76.     std::cout << ans << '\n';
  77.     for (const auto& [i, j] : used) {
  78.         std::cout << i << ' ' << j << '\n';
  79.     }
  80.     return 0;
  81. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement