結果
問題 | No.2436 Min Diff Distance |
ユーザー | Shirotsume |
提出日時 | 2023-08-18 22:38:10 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 483 ms / 2,000 ms |
コード長 | 3,970 bytes |
コンパイル時間 | 1,835 ms |
コンパイル使用メモリ | 134,404 KB |
実行使用メモリ | 25,872 KB |
最終ジャッジ日時 | 2024-11-28 08:40:17 |
合計ジャッジ時間 | 9,167 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 483 ms
22,660 KB |
testcase_04 | AC | 476 ms
22,788 KB |
testcase_05 | AC | 481 ms
22,560 KB |
testcase_06 | AC | 477 ms
22,660 KB |
testcase_07 | AC | 472 ms
22,788 KB |
testcase_08 | AC | 473 ms
22,792 KB |
testcase_09 | AC | 2 ms
5,248 KB |
testcase_10 | AC | 2 ms
5,248 KB |
testcase_11 | AC | 290 ms
25,728 KB |
testcase_12 | AC | 293 ms
25,872 KB |
testcase_13 | AC | 306 ms
20,428 KB |
testcase_14 | AC | 49 ms
5,832 KB |
testcase_15 | AC | 455 ms
22,568 KB |
testcase_16 | AC | 207 ms
12,840 KB |
testcase_17 | AC | 402 ms
21,748 KB |
testcase_18 | AC | 361 ms
21,072 KB |
testcase_19 | AC | 411 ms
21,796 KB |
testcase_20 | AC | 272 ms
13,812 KB |
testcase_21 | AC | 116 ms
8,364 KB |
testcase_22 | AC | 49 ms
5,724 KB |
ソースコード
#line 1 "graph/test/manhattan_mst.test.cpp" #define PROBLEM "https://judge.yosupo.jp/problem/manhattanmst" #line 2 "graph/manhattan_mst.hpp" #include <algorithm> #include <map> #include <numeric> #include <tuple> #include <vector> // CUT begin // Manhattan MST: 二次元平面上の頂点たちのマンハッタン距離による minimum spanning tree の O(N) 本の候補辺を列挙 // Complexity: O(N log N) // output: [(weight_uv, u, v), ...] // Verified: https://judge.yosupo.jp/problem/manhattanmst, https://www.codechef.com/problems/HKRMAN // Reference: // [1] H. Zhou, N. Shenoy, W. Nicholls, // "Efficient minimum spanning tree construction without Delaunay triangulation," // Information Processing Letters, 81(5), 271-276, 2002. template <typename T> std::vector<std::tuple<T, int, int>> manhattan_mst(std::vector<T> xs, std::vector<T> ys) { const int n = xs.size(); std::vector<int> idx(n); std::iota(idx.begin(), idx.end(), 0); std::vector<std::tuple<T, int, int>> ret; for (int s = 0; s < 2; s++) { for (int t = 0; t < 2; t++) { auto cmp = [&](int i, int j) { return xs[i] + ys[i] < xs[j] + ys[j]; }; std::sort(idx.begin(), idx.end(), cmp); std::map<T, int> sweep; for (int i : idx) { for (auto it = sweep.lower_bound(-ys[i]); it != sweep.end(); it = sweep.erase(it)) { int j = it->second; if (xs[i] - xs[j] < ys[i] - ys[j]) break; ret.emplace_back(std::abs(xs[i] - xs[j]) + std::abs(ys[i] - ys[j]), i, j); } sweep[-ys[i]] = i; } std::swap(xs, ys); } for (auto &x : xs) x = -x; } std::sort(ret.begin(), ret.end()); return ret; } #line 4 "unionfind/unionfind.hpp" #include <utility> #line 6 "unionfind/unionfind.hpp" // CUT begin // UnionFind Tree (0-indexed), based on size of each disjoint set struct UnionFind { std::vector<int> par, cou; UnionFind(int N = 0) : par(N), cou(N, 1) { iota(par.begin(), par.end(), 0); } int find(int x) { return (par[x] == x) ? x : (par[x] = find(par[x])); } bool unite(int x, int y) { x = find(x), y = find(y); if (x == y) return false; if (cou[x] < cou[y]) std::swap(x, y); par[y] = x, cou[x] += cou[y]; return true; } int count(int x) { return cou[find(x)]; } bool same(int x, int y) { return find(x) == find(y); } std::vector<std::vector<int>> groups() { std::vector<std::vector<int>> ret(par.size()); for (int i = 0; i < int(par.size()); ++i) ret[find(i)].push_back(i); ret.erase(std::remove_if(ret.begin(), ret.end(), [&](const std::vector<int> &v) { return v.empty(); }), ret.end()); return ret; } }; #line 4 "graph/test/manhattan_mst.test.cpp" #include <iostream> using namespace std; int main() { cin.tie(nullptr), ios::sync_with_stdio(false); int inf = 1000000000; int N; cin >> N; vector<int> xs(N), ys(N); vector<int> mini(N, inf), maxi(N, -inf); for (int i = 0; i < N; i++) cin >> xs[i] >> ys[i]; UnionFind uf(N); long long weight = 0; vector<pair<int, int>> edges; for (auto [w, i, j] : manhattan_mst(xs, ys)) { mini[i] = min(mini[i], w); mini[j] = min(mini[j], w); } int maxx = -inf; int maxy = -inf; int minx = inf; int miny = inf; for(int i = 0; i < N; i++){ int x = xs[i] + ys[i]; int y = xs[i] - ys[i]; maxx = max(maxx, x); minx = min(minx, x); maxy = max(maxy, y); miny = min(miny, y); } for(int i = 0; i < N; i++){ int x = xs[i] + ys[i]; int y = xs[i] - ys[i]; maxi[i] = max({maxx - x, x - minx, maxy - y, y - miny}); } int ans = inf; for(int i = 0; i < N; i++){ ans = min(ans, maxi[i] - mini[i]); } cout << ans << '\n'; }