Problem p01341 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

// 并查集相关数据与算法
#define MAX_N 10000 + 16
int parent[MAX_N];
int height[MAX_N];

void init(const int &n) {
  for (int i = 0; i < n; ++i) {
    parent[i] = i;
    height[i] = 0;
  }
}

int find(const int &x) {
  if (parent[x] == x) {
    return x;
  } else {
    return parent[x] = find(parent[x]);
  }
}

void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y) {
    return;
  }

  if (height[x] < height[y]) {
    parent[x] = y;
  } else {
    parent[y] = x;
    if (height[x] == height[y]) {
      ++height[x];
    }
  }
}

bool same(const int &x, const int &y) { return find(x) == find(y); }
// End Of 并查集

#define MAX_E MAX_N *MAX_N / 2 + 1
struct edge {
  int u, v;
  double cost;
  edge(int u = 0, int v = 0, double cost = 0) : u(u), v(v), cost(cost) {}
  bool operator<(const edge &e2) const { return cost > e2.cost; }
};

edge es[MAX_E];
int V, E;
double kruskal() {
  sort(es, es + E); // 按照权值从小到大排序
  init(V);
  double res = 0;
  for (int i = 0; i < E; ++i) {
    edge e = es[i];
    if (!same(e.u, e.v)) {
      unite(e.u, e.v);
    } else {
      res += e.cost;
    }
  }

  return res;
}

pair<int, int> pile[MAX_N];

///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[]) {
  cin >> V >> E;

  for (int i = 0; i < V; ++i) {
    cin >> pile[i].first >> pile[i].second;
  }

  for (int i = 0; i < E; ++i) {
    cin >> es[i].u >> es[i].v;
    --es[i].u;
    --es[i].v;
    int dx = pile[es[i].u].first - pile[es[i].v].first;
    int dy = pile[es[i].u].second - pile[es[i].v].second;
    es[i].cost = sqrt(dx * dx + dy * dy);
  }

  cout.setf(ios::showpoint);
  cout.precision(3);
  cout.setf(ios::fixed);
  cout << kruskal() << endl;
  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

struct edge {
  int u, v;
  double w;
  edge() { u = v = w = 0; }
  edge(int uu, int vv, double ww) {
    u = uu;
    v = vv;
    w = ww;
  }
  bool operator<(const edge &b) const { return w > b.w; }
};

const int MAX_N = 10001;
pair<int, int> points[MAX_N];
const int MAX_M = MAX_N * (MAX_N - 1) / 2;
edge edges[MAX_M];
// point points[MAX_N];//start from point_1

int par[MAX_N];
int val[MAX_N];
void init(int n) {
  for (int i = 1; i <= n; i++) {
    par[i] = i;
    val[i] = 0;
  }
}

int find(int x) {
  int root = x;
  while (root != par[root])
    root = par[root];
  while (x != root) {
    int t = par[x];
    par[x] = root;
    x = t;
  }
  return root;
}

bool same(int x, int y) {
  x = find(x);
  y = find(y);
  return x == y;
}

void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (val[x] < val[y])
    par[x] = y;
  else
    par[y] = x;
  if (val[x] == val[y])
    val[x]++;
}

int main() {
  freopen("in.txt", "r", stdin);
  int N, M;
  cin >> N >> M;
  for (int i = 1; i <= N; i++) {
    cin >> points[i].first >> points[i].second;
  }
  int p, q;
  int x1, x2, y1, y2;
  for (int i = 0; i < M; i++) {
    cin >> p >> q;
    edges[i].u = p;
    edges[i].v = q;
    x1 = points[p].first;
    x2 = points[q].first;
    y1 = points[p].second;
    y2 = points[q].second;
    edges[i].w = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  }
  sort(edges, edges + M);
  double res = 0;
  init(N);
  for (int i = 0; i < M; i++) {
    int p = edges[i].u, q = edges[i].v;
    if (same(p, q)) {
      res += edges[i].w;
    } else {
      unite(p, q);
    }
  }
  printf("%.3lf", res);

  fclose(stdin);
}