Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- |~~~~~~~|
- | |
- | |
- | |
- | |
- | |
- |~.\\\_\~~~~~~~~~~~~~~xx~~~ ~~~~~~~~~~~~~~~~~~~~~/_//;~|
- | \ o \_ ,XXXXX), иисус _..-~ o / |
- | ~~\ ~-. XXXXX`)))), _.--~~ .-~~~ |
- ~~~~~~~`\ ~\~~~XXX' _/ ';)) |~~~~~~..-~ _.-~ ~~~~~~~
- `\ ~~--`_\~\, ;;;\)__.---.~~~ _.-~
- ~-. `:;;/;; \ _..-~~
- ~-._ `'' /-~-~
- `\ / /
- | , | |
- | ' / |
- \/; |
- ;; |
- `; . |
- |~~~-----.....|
- | \ \
- | /\~~--...__ |
- (| `\ __-\|
- || \_ /~ |
- |) \~-' |
- | | \ '
- | | \ :
- \ | | |
- | ) ( )
- \ /; /\ |
- | |/ |
- | | |
- \ .' ||
- | | | |
- ( | | |
- | \ \ |
- || o `.)|
- |`\\\\) |
- | |
- | |
- | |
- */
- #include <bits/stdc++.h>
- #pragma GCC optimize("Ofast")
- #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
- #pragma GCC optimize ("unroll-loops")
- using namespace std;
- #define TASK "tree"
- typedef unsigned short int ll;
- typedef long double ld;
- typedef pair<ll, ll> par;
- typedef unsigned int ui;
- #define all(x) (x).begin(), (x).end()
- #define rall(x) (x).rbegin(), (x).rend()
- #define X first
- #define Y second
- #define pw(x) (1ll << (x))
- #define _ inline
- ll rnd() { return (rand() << 16) + rand(); }
- ll p[50001], r[50001];
- _ ll findP(ll x) { return (p[x] == x ? x : p[x] = findP(p[x]));}
- _ void Merge(ll a, ll b) {
- a = findP(a), b = findP(b);
- if (a == b) return;
- if (r[a] < r[b]) swap(a, b);
- if (r[a] == r[b]) r[a]++;
- p[b] = a;
- }
- struct edge {
- ll v, to;
- int w;
- edge() {}
- edge(ll v, ll to, int w) : v(v), to(to), w(w) {}
- };
- bool operator < (edge a, edge b) {
- return a.w < b.w;
- }
- ll C = 650;
- _ int f(par a, par b) {
- return (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y);
- }
- par q[50001];
- pair<par, ll> a[50001];
- _ int source() {
- ll n;
- cin >> n;
- bool flag = (n >= 21000);
- for (int i = 0; i < n; ++i) {
- p[i] = i;
- r[i] = 0;
- }
- for (int i = 0; i < n; ++i) {
- cin >> a[i].X.Y >> a[i].X.X;
- a[i].Y = i;
- }
- sort(a, a + n);
- vector<edge> e;
- e.reserve(50001 * C);
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < C; ++j) {
- if (i + j == n) break;
- int w = f(a[i].X, a[i + j].X);
- if (flag && w >= 10000) continue;
- e.push_back(edge(i, i + j, w));
- }
- }
- sort(all(e));
- ld ans = 0;
- ll sizeq = 0;
- for (int i = 0; i < e.size(); ++i) {
- edge cur = e[i];
- ll v1 = cur.v, to1 = cur.to;
- ll v = findP(cur.v), to = findP(cur.to);
- if (v == to) continue;
- Merge(v, to);
- q[sizeq++] = {v1, to1};
- ans += sqrt(cur.w);
- }
- cout << fixed << setprecision(15) << ans << '\n';
- for (int i = 0; i < sizeq; ++i) {
- cout << a[q[i].X].Y + 1 << ' ' << a[q[i].Y].Y + 1 << '\n';
- }
- return 0;
- }
- int main() {
- #ifdef aokigahara
- assert(freopen("input.txt", "r", stdin));
- assert(freopen("output.txt", "w", stdout));
- #else
- //freopen(TASK".in", "r", stdin);
- //freopen(TASK".out", "w", stdout);
- #endif
- srand(time(NULL));
- ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- source();
- #ifdef aokigahara
- cerr << "TIME :: " << clock() * 1.0 / CLOCKS_PER_SEC;
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement