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

#include <bits/stdc++.h>
// #include <boost/multiprecision/cpp_int.hpp>
using namespace std;
// using namespace boost::multiprecision;
typedef long long int ll;
typedef long double ld;
#define PI 3.141592653589793
#define MOD 1000000007
#define ALL(obj) (obj).begin(), (obj).end()
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const ll INF = 1LL << 60;

// 四方向への移動ベクトル
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

struct edge { // グラフに使うヤツ
  ll from, to, cost;
};

typedef vector<vector<edge>> G;
ll gcd(ll a, ll b) {
  if (a % b == 0)
    return (b);
  else
    return (gcd(b, a % b));
}

struct UnionFind {
  vector<ll> par, rank, con;
  UnionFind(ll n) : par(n, -1), rank(n, 0), con(n, 1) {}
  ll root(ll x) {
    if (par[x] < 0)
      return x;
    return par[x] = root(par[x]);
  }
  bool unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y); // merge technique
    par[x] += par[y];
    par[y] = x;
    con[x] += con[y];
    return true;
  }
  bool same(ll x, ll y) {
    ll rx = root(x);
    ll ry = root(y);
    return rx == ry;
  }
  ll size(int x) { return -par[root(x)]; }
};

int main() {
  ll n, m, ans = 1;
  cin >> n >> m;
  UnionFind uf(n);
  for (ll i = 0; i < m; i++) {
    ll a, b;
    cin >> a >> b;
    a--;
    b--;
    uf.unite(a, b);
  }
  bool visited[n];
  fill(visited, visited + n, false);
  for (ll i = 0; i < n; i++) {
    ans = max(ans, uf.size(i));
  }
  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
// #include <boost/multiprecision/cpp_int.hpp>
using namespace std;
// using namespace boost::multiprecision;
typedef long long int ll;
typedef long double ld;
#define PI 3.141592653589793
#define MOD 1000000007
#define ALL(obj) (obj).begin(), (obj).end()
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
const ll INF = 1LL << 60;

// 四方向への移動ベクトル
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

struct edge { // グラフに使うヤツ
  ll from, to, cost;
};

typedef vector<vector<edge>> G;
ll gcd(ll a, ll b) {
  if (a % b == 0)
    return (b);
  else
    return (gcd(b, a % b));
}

struct UnionFind {
  vector<ll> par, rank, con;
  UnionFind(ll n) : par(n, -1), rank(n, 0), con(n, 1) {}
  ll root(ll x) {
    if (par[x] < 0)
      return x;
    return par[x] = root(par[x]);
  }
  bool unite(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y); // merge technique
    par[x] += par[y];
    par[y] = x;
    con[x] += con[y];
    return true;
  }
  bool same(ll x, ll y) {
    ll rx = root(x);
    ll ry = root(y);
    return rx == ry;
  }
  ll size(int x) { return -par[root(x)]; }
};

int main() {
  ll n, m, ans = 1;
  cin >> n >> m;
  UnionFind uf(n);
  for (ll i = 0; i < m; i++) {
    ll a, b;
    cin >> a >> b;
    a--;
    b--;
    uf.unite(a, b);
  }
  bool visited[n];
  fill(visited, visited + n, false);
  for (ll i = 0; i < n; i++) {
    if (visited[i])
      continue;
    ll con = 1;
    for (ll j = i + 1; j < n; j++) {
      if (uf.same(i, j)) {
        visited[j] = true;
        con++;
      }
    }
    ans = max(con, ans);
  }
  cout << ans << endl;
  return 0;
}