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

#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; }
};

struct point {
  int first, second;
  point() { first = second = 0; }
  point(int xx, int yy) {
    first = xx;
    second = yy;
  }
};
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() {
  int N, M;
  cin >> N >> M;
  point *points = new point[2 * N];
  edge *edges = new edge[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);
  delete[] points;
  delete[] edges;
}


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; }
};

struct point {
  int first, second;
  point() { first = second = 0; }
  point(int xx, int yy) {
    first = xx;
    second = yy;
  }
};
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() {
  int N, M;
  cin >> N >> M;
  point *points = new point[2 * N];
  edge *edges = new edge[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);
  delete[] points;
  delete[] edges;
}