Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // Created by afusikey on 20.03.19.
- //
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <cmath>
- #include <iomanip>
- #include <stack>
- using namespace std;
- const int INF = 1000000000;
- struct sort_pred {
- bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
- return left.second < right.second;
- }
- };
- double distance(pair<int, int> p1, pair<int, int> p2){
- double dist = sqrt((p1.first - p2.first) *
- (p1.first - p2.first) +
- (p1.second - p2.second) *
- (p1.second - p2.second));
- return dist;
- }
- int main() {
- std::ios_base::sync_with_stdio(false), std::cin.tie(nullptr);
- int n;
- cin >> n;
- auto points = vector<pair<int, int>>(n);
- auto g = vector<vector<double>>(n);
- for (int i = 0; i < n; i ++) {
- g[i] = vector<double>(n);
- }
- for (int i = 0; i < n; i ++)
- {
- cin >> points[i].first >> points[i].second;
- }
- sort(points.begin(), points.end());
- for (int i = 0; i < points.size(); i ++){
- int start = 0;
- int end = points.size() - 1;
- if (points.size() > 800) {
- start = i - 250;
- end = i + 250;
- if (start < 0) {
- end -= start;
- start = 0;
- }
- if (end >= points.size()) {
- start -= end - points.size();
- end = points.size() - 1;
- }
- vector<pair<int, int>> near(500);
- for (int j = 0; j < 500; j ++){
- near[j] = points[start + j];
- }
- sort(near.begin(), near.end(), sort_pred());
- for (int j = 0; j <= 40; j ++) {
- double dist = distance(points[i], near[j]);
- g[i][j] = dist;
- g[j][i] = dist;
- }
- } else
- {
- for (int j = start; j <= end; j ++) {
- double dist = distance(points[i], points[j]);
- g[i][j] = dist;
- g[j][i] = dist;
- }
- }
- }
- double cost = 0;
- vector<bool> used (n);
- vector<double> min_e (n, INF), sel_e (n, -1);
- min_e[0] = 0;
- auto ans = stack<pair<int, int>>();
- for (int i = 0; i < n; ++i) {
- int v = -1;
- for (int j = 0; j < n; ++j)
- if (!used[j] && (v == -1 || min_e[j] < min_e[v]))
- v = j;
- if (min_e[v] == INF) {
- cout << "No MST!";
- exit(0);
- }
- used[v] = true;
- if (sel_e[v] != -1){
- cost += min_e[v];
- ans.push({v+1, sel_e[v]+1});
- }
- //cout << v << " " << sel_e[v] << endl;
- for (int to=0; to<n; ++to)
- if (g[v][to] < min_e[to]) {
- min_e[to] = g[v][to];
- sel_e[to] = v;
- }
- }
- cout << setprecision(15)<< fixed << cost << "\n";
- while (!ans.empty()){
- auto e = ans.top();
- ans.pop();
- cout << e.first << " " << e.second << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement