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

#include <bits/stdc++.h>
#include <iostream>
using namespace std;
using ll = long long;

struct UnionFind {
  // comment: https://youtu.be/TdR816rqc3s?t=6822 (AtCoder)
  // each element represent a node where value points to their group
  // representative
  vector<int> d;
  // initialize
  UnionFind(int n = 0) : d(n, -1) {}
  // find the root node for x (the root of the group where x belongs to)
  int findRoot(int x) {
    if (d[x] < 0)
      return x;                   // root has value < 0 (- size of group)
    return d[x] = findRoot(d[x]); // find root recursively (also update values
                                  // of intermediate node)
  }
  // combine group X (x belongs) and group Y (y belongs) into one big group
  bool uniteTwoNodes(int x, int y) {
    // find the root of X and Y
    x = findRoot(x);
    y = findRoot(y);
    // x and y in the same group already
    if (x == y)
      return false; // can't join
    // combine 2 groups by joining the smaller group to the bigger one
    // size of group = - (value of root node)
    // want to join Y into X (so X need to be the bigger one)
    // if X is the smaller one (-d[x] < -d[y])
    if (d[x] > d[y])
      swap(x, y); // swap X to be the bigger group
    d[x] += d[y]; // update the size of new X (sum of sizes of X and Y)
    d[y] = x;
    return true; // successfully joint
  }

  // check if 2 nodes are in the same group
  bool inSameGroup(int x, int y) { return findRoot(x) == findRoot(y); }
  // size of Group where x belongs to
  int sizeOfGroup(int x) { return -d[findRoot(x)]; }
};

int main() {
  int n, m;
  cin >> n >> m;

  // initialize a unionFindStructure with n nodes
  UnionFind uf(n);

  // generate UnionFind based on inputs
  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b;
    --a;
    --b; // index starts at 0
    uf.uniteTwoNodes(a, b);
  }

  // find group with largest size
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    ans = max(ans, uf.sizeOfGroup(i));
  }

  cout << ans << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;
using ll = long long;

int numFriends(int N, int c, vector<vector<bool>> g, bool *v_p, int *l) {
  int numF = 0;
  for (int i = 0; i < N; ++i) {
    // not current node, connected and not visited
    if ((i != c) && (g[c][i]) && (!v_p[i])) {
      // visit i
      v_p[i] = true;
      // add numFriends of i
      if (l[i] != -1) {
        numF += l[i] + 1;
      } else {
        numF += numFriends(N, i, g, v_p, l) + 1;
      }
    }
  }

  l[c] = numF;
  return numF;
}

int main() {
  int N, M;
  cin >> N >> M;

  // friendship graph
  vector<vector<bool>> g;
  // initialize friendship graph
  for (int i = 0; i < N; ++i) {
    vector<bool> tmp;
    for (int j = 0; j < N; ++j) {
      tmp.push_back(false);
    }
    g.push_back(tmp);
  }

  int f1, f2;
  // generate friendship graph
  for (int m = 0; m < M; ++m) {
    cin >> f1 >> f2;
    g[f1 - 1][f2 - 1] = true;
    g[f2 - 1][f1 - 1] = true;
  }

  // visited points
  bool v[200001];
  // calculated length when i is the start point
  int l[200001];
  for (int i = 0; i < N; ++i) {
    v[i] = false;
    l[i] = -1;
  }

  int largestGroup = 0;
  // loop through all nodes (as starting node)
  for (int start = 0; start < N; ++start) {
    // continue track if s is not visited yet (new starting point)
    if (!v[start]) {
      // visit start
      v[start] = true;

      int currentGroupSize = numFriends(N, start, g, v, l) + 1;
      // if found a larger group
      largestGroup =
          (currentGroupSize > largestGroup) ? currentGroupSize : largestGroup;
    }
  }

  cout << largestGroup << endl;

  return 0;
}