Problem p03440 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <deque>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
using namespace std;
const long long mod = 1000000007;
const long long inf = mod * mod;
const long long d2 = (mod + 1) / 2;
const double EPS = 1e-6;
const double PI = acos(-1.0);
int ABS(int a) { return max(a, -a); }
long long ABS(long long a) { return max(a, -a); }
int UF[110000];
int UF2[110000];
int FIND(int a) {
  if (UF[a] < 0)
    return a;
  return UF[a] = FIND(UF[a]);
}
void UNION(int a, int b) {
  a = FIND(a);
  b = FIND(b);
  if (a == b)
    return;
  UF[a] += UF[b];
  UF[b] = a;
}
int FIND2(int a) {
  if (UF2[a] < 0)
    return a;
  return UF2[a] = FIND2(UF2[a]);
}
void UNION2(int a, int b) {
  a = FIND2(a);
  b = FIND2(b);
  if (a == b)
    return;
  UF2[a] += UF2[b];
  UF2[b] = a;
}
int p[110000];
vector<int> v[110000];
pair<int, int> z[110000];
int use[110000];
int mi[110000];
int main() {
  int a, b;
  scanf("%d%d", &a, &b);
  if (a == 1) {
    printf("0\n");
    return 0;
  }
  for (int i = 0; i < a; i++)
    UF[i] = UF2[i] = -1;
  for (int i = 0; i < a; i++)
    scanf("%d", p + i);
  if (a == 2 && b == 0) {
    printf("%d\n", p[0] + p[1]);
    return 0;
  }
  for (int i = 0; i < b; i++) {
    int s, t;
    scanf("%d%d", &s, &t);
    UNION(s, t);
  }
  for (int i = 0; i < a; i++) {
    v[FIND(i)].push_back(p[i]);
  }
  for (int i = 0; i < a; i++)
    std::sort(v[i].begin(), v[i].end());
  long long ret = 0;
  int cn = 0;
  int sz = 0;
  int at;
  for (int i = 0; i < a; i++) {
    if (v[i].size() < 2)
      continue;
    cn++;
    // ret+=v[i][0];
    for (int j = 0; j < v[i].size(); j++) {
      z[sz++] = make_pair(v[i][j], i);
    }
  }
  std::sort(z, z + sz);
  if (cn == 1) {
  } else {
    for (int i = 0; i < sz; i++) {
      if (mi[z[i].second])
        ;
      else {
        mi[z[i].second] = 1;
        ret += z[i].first;
        use[i] = 1;
      }
    }
    int rem = cn - 2;
    for (int i = 0; rem; i++) {
      if (!use[i]) {
        rem--;
        ret += z[i].first;
        use[i] = 1;
      }
    }
  }
  at = 0;
  for (int i = 0; i < a; i++) {
    if (v[i].size() == 1) {
      ret += v[i][0];
      bool ok = false;
      while (at < sz) {
        if (!use[at]) {
          ok = true;
          use[at] = 1;
          ret += z[at].first;
          at++;
          break;
        }
        at++;
      }
      if (!ok) {
        printf("Impossible\n");
        return 0;
      }
    }
  }
  printf("%lld\n", ret);
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <deque>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
using namespace std;
const long long mod = 1000000007;
const long long inf = mod * mod;
const long long d2 = (mod + 1) / 2;
const double EPS = 1e-6;
const double PI = acos(-1.0);
int ABS(int a) { return max(a, -a); }
long long ABS(long long a) { return max(a, -a); }
int UF[110000];
int UF2[110000];
int FIND(int a) {
  if (UF[a] < 0)
    return a;
  return UF[a] = FIND(UF[a]);
}
void UNION(int a, int b) {
  a = FIND(a);
  b = FIND(b);
  if (a == b)
    return;
  UF[a] += UF[b];
  UF[b] = a;
}
int FIND2(int a) {
  if (UF2[a] < 0)
    return a;
  return UF2[a] = FIND2(UF2[a]);
}
void UNION2(int a, int b) {
  a = FIND2(a);
  b = FIND2(b);
  if (a == b)
    return;
  UF2[a] += UF2[b];
  UF2[b] = a;
}
int p[110000];
vector<int> v[110000];
pair<int, int> z[110000];
int use[110000];
int mi[110000];
int main() {
  int a, b;
  scanf("%d%d", &a, &b);
  if (a == 1) {
    printf("0\n");
    return 0;
  }
  if (a > 1 && b == 0) {
    printf("Impossible\n");
    return 0;
  }
  for (int i = 0; i < a; i++)
    UF[i] = UF2[i] = -1;
  for (int i = 0; i < a; i++)
    scanf("%d", p + i);
  if (a == 2 && b == 0) {
    printf("%d\n", p[0] + p[1]);
    return 0;
  }
  for (int i = 0; i < b; i++) {
    int s, t;
    scanf("%d%d", &s, &t);
    UNION(s, t);
  }
  for (int i = 0; i < a; i++) {
    v[FIND(i)].push_back(p[i]);
  }
  for (int i = 0; i < a; i++)
    std::sort(v[i].begin(), v[i].end());
  long long ret = 0;
  int cn = 0;
  int sz = 0;
  int at;
  for (int i = 0; i < a; i++) {
    if (v[i].size() < 2)
      continue;
    cn++;
    // ret+=v[i][0];
    for (int j = 0; j < v[i].size(); j++) {
      z[sz++] = make_pair(v[i][j], i);
    }
  }
  std::sort(z, z + sz);
  if (cn == 1) {
  } else {
    for (int i = 0; i < sz; i++) {
      if (mi[z[i].second])
        ;
      else {
        mi[z[i].second] = 1;
        ret += z[i].first;
        use[i] = 1;
      }
    }
    int rem = cn - 2;
    for (int i = 0; rem; i++) {
      if (!use[i]) {
        rem--;
        ret += z[i].first;
        use[i] = 1;
      }
    }
  }
  at = 0;
  for (int i = 0; i < a; i++) {
    if (v[i].size() == 1) {
      ret += v[i][0];
      bool ok = false;
      while (at < sz) {
        if (!use[at]) {
          ok = true;
          use[at] = 1;
          ret += z[at].first;
          at++;
          break;
        }
        at++;
      }
      if (!ok) {
        printf("Impossible\n");
        return 0;
      }
    }
  }
  printf("%lld\n", ret);
}