Problem p03440 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef pair<P, int> PP;
#define int long long
int a[114514], par[114514], rnk[114514];
vector<int> cst[100004];
void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    rnk[i] = 0;
  }
}
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (rnk[x] < rnk[y]) {
    par[x] = y;
  } else {
    par[y] = x;
    if (rnk[x] == rnk[y])
      rnk[x]++;
  }
}
bool same(int x, int y) { return find(x) == find(y); }
signed main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    cin >> a[i];
  init(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    unite(x, y);
  }

  for (int i = 0; i < n; i++) {
    cst[find(i)].push_back(a[i]);
  }

  int ans = 0;
  int need = 0, ki = 0;
  ;

  for (int i = 0; i < n; i++) {
    if (cst[i].size())
      ki++;
    sort(cst[i].begin(), cst[i].end());
  }
  need = ki * 2 - 2;
  if (!need) {
    cout << 0 << endl;
    return 0;
  } else if (need > n) {
    puts("Impossible");
    return 0;
  } else {
    for (int i = 0; i < n; i++) {
      if (cst[i].size())
        ans += cst[i][0];
    }
    vector<int> V;
    for (int i = 0; i < n; i++) {
      for (int j = 1; j < cst[i].size(); i++)
        V.push_back(cst[i][j]);
    }
    sort(V.begin(), V.end());
    for (int i = 0; i < need - ki; i++) {
      ans += V[i];
    }
    cout << ans << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef pair<int, int> P;
typedef pair<P, int> PP;
#define int long long
int a[114514], par[114514], rnk[114514];
vector<int> cst[100004];
void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    rnk[i] = 0;
  }
}
int find(int x) {
  if (par[x] == x)
    return x;
  return par[x] = find(par[x]);
}
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;
  if (rnk[x] < rnk[y]) {
    par[x] = y;
  } else {
    par[y] = x;
    if (rnk[x] == rnk[y])
      rnk[x]++;
  }
}
bool same(int x, int y) { return find(x) == find(y); }
signed main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    cin >> a[i];
  init(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    unite(x, y);
  }

  for (int i = 0; i < n; i++) {
    cst[find(i)].push_back(a[i]);
  }

  int ans = 0;
  int need = 0, ki = 0;
  ;

  for (int i = 0; i < n; i++) {
    if (cst[i].size())
      ki++;
    sort(cst[i].begin(), cst[i].end());
  }
  need = ki * 2 - 2;
  if (!need) {
    cout << 0 << endl;
    return 0;
  } else if (need > n) {
    puts("Impossible");
    return 0;
  } else {
    for (int i = 0; i < n; i++) {
      if (cst[i].size())
        ans += cst[i][0];
    }
    vector<int> V;
    for (int i = 0; i < n; i++) {
      for (int j = 1; j < cst[i].size(); j++)
        V.push_back(cst[i][j]);
    }
    sort(V.begin(), V.end());
    for (int i = 0; i < need - ki; i++) {
      ans += V[i];
    }
    cout << ans << endl;
  }
}