Problem p02536 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#include <unistd.h>

#if __has_include(<local.h>)
// #include <local.h>
#endif

using namespace std;

typedef long long int LL;
typedef long long int LLint;

struct dsu {
public:
  dsu() : _n(0) {}
  dsu(int n) : _n(n), parent_or_size(n, -1) {}

  int merge(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    int x = leader(a), y = leader(b);
    if (x == y)
      return x;
    if (-parent_or_size[x] < -parent_or_size[y])
      std::swap(x, y);
    parent_or_size[x] += parent_or_size[y];
    parent_or_size[y] = x;
    return x;
  }

  bool same(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    return leader(a) == leader(b);
  }

  int leader(int a) {
    assert(0 <= a && a < _n);
    if (parent_or_size[a] < 0)
      return a;
    return parent_or_size[a] = leader(parent_or_size[a]);
  }

  int size(int a) {
    assert(0 <= a && a < _n);
    return -parent_or_size[leader(a)];
  }

  std::vector<std::vector<int>> groups() {
    std::vector<int> leader_buf(_n), group_size(_n);
    for (int i = 0; i < _n; i++) {
      leader_buf[i] = leader(i);
      group_size[leader_buf[i]]++;
    }
    std::vector<std::vector<int>> result(_n);
    for (int i = 0; i < _n; i++) {
      result[i].reserve(group_size[i]);
    }
    for (int i = 0; i < _n; i++) {
      result[leader_buf[i]].push_back(i);
    }
    result.erase(
        std::remove_if(result.begin(), result.end(),
                       [&](const std::vector<int> &v) { return v.empty(); }),
        result.end());
    return result;
  }

private:
  int _n;
  // root node: -1 * component size
  // otherwise: parent
  std::vector<int> parent_or_size;
};

// Faster Program
#define endl "\\n"

// Faster Coding
#define ED return
#define GET(a)                                                                 \\
  int a;                                                                       \\
  cin >> a
#define DGET(a)                                                                \\
  double a;                                                                    \\
  cin >> a
#define SGET(a)                                                                \\
  string a;                                                                    \\
  cin >> a
#define CGET(a)                                                                \\
  char a;                                                                      \\
  cin >> a
#define PRINT(a) cout << a << "\\n"
#define ANS(a, b)                                                              \\
  int a;                                                                       \\
  cin >> a;                                                                    \\
  cout << b << "\\n"
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define SORT(vec) sort(vec.begin(), vec.end())
#define REV(vec) reverse(vec.begin(), vec.end())
#define ALL(x) (x).begin(), (x).end()

// As Function
#define UP(a, b) ((a + (b - 1)) / (b))
#define IPOW(x, y) LL(pow(x, y))

// Debug
#ifdef LOCAL_H
#define TEST cout << "OK\\n"
#define DEBUG(a) a
#else
#define TEST
#define DEBUG(a)
#endif

#ifdef LOCAL_H
[[maybe_unused]]
#endif
const double PI = M_PI;
#ifdef LOCAL_H
[[maybe_unused]]
#endif
const int INF = int(999999999);
#ifdef LOCAL_H
[[maybe_unused]]
#endif
const LL LL_INF = LL(999999999999999999);
#ifdef LOCAL_H
[[maybe_unused]]
#endif
const long long MOD = int(1000000007);

// Settings
#ifdef LOCAL_H
const bool DO_BENCHMARK = true;
#endif
const int DOUBLE_ACCURACY = 15;
const int RUN_SOLVE = 1;

#ifndef LOCAL_H
const bool DO_BENCHMARK = false;
#endif

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(DOUBLE_ACCURACY);
  for (int do_solve_time = 0; do_solve_time < RUN_SOLVE; do_solve_time++) {
    void solve();
    if (DO_BENCHMARK) {
      clock_t clock_start = clock();
      solve();
      clock_t clock_end = clock();
      const double time = static_cast<double>(clock_end - clock_start) /
                          CLOCKS_PER_SEC * 1000.0;
      cout << "\\n------------------------------------\\n" << time << "[ms]\\n";
    } else
      solve();
  }
}

/*------------------------------↓ここからコード↓----------------------------------*/
void solve() {
  int N, M;
  cin >> N >> M;
  dsu d(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    d.merge(a - 1, b - 1);
  }
  vector<int> group(N);
  for (int i = 0; i < N; i++) {
    group[i] = d.size(i);
  }
  SORT(group);
  int ans = -1;
  for (int i = 0; i < N;) {
    ans++;
    i += group[i];
  }
  cout << ans << endl;
  return;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <unistd.h>

#if __has_include(<local.h>)
// #include <local.h>
#endif

using namespace std;

typedef long long int LL;
typedef long long int LLint;

struct dsu {
public:
  dsu() : _n(0) {}
  dsu(int n) : _n(n), parent_or_size(n, -1) {}

  int merge(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    int x = leader(a), y = leader(b);
    if (x == y)
      return x;
    if (-parent_or_size[x] < -parent_or_size[y])
      std::swap(x, y);
    parent_or_size[x] += parent_or_size[y];
    parent_or_size[y] = x;
    return x;
  }

  bool same(int a, int b) {
    assert(0 <= a && a < _n);
    assert(0 <= b && b < _n);
    return leader(a) == leader(b);
  }

  int leader(int a) {
    assert(0 <= a && a < _n);
    if (parent_or_size[a] < 0)
      return a;
    return parent_or_size[a] = leader(parent_or_size[a]);
  }

  int size(int a) {
    assert(0 <= a && a < _n);
    return -parent_or_size[leader(a)];
  }

  std::vector<std::vector<int>> groups() {
    std::vector<int> leader_buf(_n), group_size(_n);
    for (int i = 0; i < _n; i++) {
      leader_buf[i] = leader(i);
      group_size[leader_buf[i]]++;
    }
    std::vector<std::vector<int>> result(_n);
    for (int i = 0; i < _n; i++) {
      result[i].reserve(group_size[i]);
    }
    for (int i = 0; i < _n; i++) {
      result[leader_buf[i]].push_back(i);
    }
    result.erase(
        std::remove_if(result.begin(), result.end(),
                       [&](const std::vector<int> &v) { return v.empty(); }),
        result.end());
    return result;
  }

private:
  int _n;
  // root node: -1 * component size
  // otherwise: parent
  std::vector<int> parent_or_size;
};

// Faster Program
#define endl "\\n"

// Faster Coding
#define ED return
#define GET(a)                                                                 \\
  int a;                                                                       \\
  cin >> a
#define DGET(a)                                                                \\
  double a;                                                                    \\
  cin >> a
#define SGET(a)                                                                \\
  string a;                                                                    \\
  cin >> a
#define CGET(a)                                                                \\
  char a;                                                                      \\
  cin >> a
#define PRINT(a) cout << a << "\\n"
#define ANS(a, b)                                                              \\
  int a;                                                                       \\
  cin >> a;                                                                    \\
  cout << b << "\\n"
#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define SORT(vec) sort(vec.begin(), vec.end())
#define REV(vec) reverse(vec.begin(), vec.end())
#define ALL(x) (x).begin(), (x).end()

// As Function
#define UP(a, b) ((a + (b - 1)) / (b))
#define IPOW(x, y) LL(pow(x, y))

// Debug
#ifdef LOCAL_H
#define TEST cout << "OK\\n"
#define DEBUG(a) a
#else
#define TEST
#define DEBUG(a)
#endif

#ifdef LOCAL_H
[[maybe_unused]]
#endif
const double PI = M_PI;
#ifdef LOCAL_H
[[maybe_unused]]
#endif
const int INF = int(999999999);
#ifdef LOCAL_H
[[maybe_unused]]
#endif
const LL LL_INF = LL(999999999999999999);
#ifdef LOCAL_H
[[maybe_unused]]
#endif
const long long MOD = int(1000000007);

// Settings
#ifdef LOCAL_H
const bool DO_BENCHMARK = true;
#endif
const int DOUBLE_ACCURACY = 15;
const int RUN_SOLVE = 1;

#ifndef LOCAL_H
const bool DO_BENCHMARK = false;
#endif

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(DOUBLE_ACCURACY);
  for (int do_solve_time = 0; do_solve_time < RUN_SOLVE; do_solve_time++) {
    void solve();
    if (DO_BENCHMARK) {
      clock_t clock_start = clock();
      solve();
      clock_t clock_end = clock();
      const double time = static_cast<double>(clock_end - clock_start) /
                          CLOCKS_PER_SEC * 1000.0;
      cout << "\\n------------------------------------\\n" << time << "[ms]\\n";
    } else
      solve();
  }
}

/*------------------------------↓ここからコード↓----------------------------------*/
void solve() {
  int N, M;
  cin >> N >> M;
  dsu d(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    d.merge(a - 1, b - 1);
  }
  int ans = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (!d.same(i, j)) {
        ans++;
        d.merge(i, j);
      }
    }
  }
  cout << ans << endl;
  return;
}