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

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;

int main() {
  int H, W, M;
  cin >> H >> W >> M;
  vector<int> cntX(H);
  fill(cntX.begin(), cntX.end(), 0);
  vector<int> cntY(W);
  fill(cntY.begin(), cntY.end(), 0);
  vector<pair<int, int>> t(M);
  set<pair<int, int>> S;
  for (int i = 0; i < M; i++) {
    cin >> t[i].first >> t[i].second;
    cntX[t[i].first - 1]++;
    cntY[t[i].second - 1]++;
    t[i].first--;
    t[i].second--;
    S.insert(t[i]);
  }
  sort(t.begin(), t.end());
  int ansX = 0;
  int ansY = 0;
  vector<int> xi;
  for (int i = 0; i < H; i++) {
    ansX = max(ansX, cntX[i]);
  }
  for (int i = 0; i < H; i++) {
    if (ansX == cntX[i]) {
      xi.emplace_back(i);
    }
  }

  for (int i = 0; i < W; i++) {
    ansY = max(ansY, cntY[i]);
  }
  vector<int> yi;
  for (int i = 0; i < W; i++) {
    if (ansY == cntY[i]) {
      yi.emplace_back(i);
    }
  }
  for (int i : xi) {
    for (int j : yi) {
      if (S.find(make_pair(i, j)) == S.end()) {
        cout << ansX + ansY << endl;
        return 0;
      }
    }
  }
  cout << ansX + ansY - 1 << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;

class UnionFindTree {
private:
  int N;
  int *rootnum;
  int *rank;
  int *unionnum;

public:
  UnionFindTree(int n) {
    /*0からn-1までの要素をunionとしてもつ*/
    N = n;
    rootnum = new int[N];
    rank = new int[N];
    unionnum = new int[N];
    for (int i = 0; i < N; i++) {
      rootnum[i] = i;
      rank[i] = 0;
      unionnum[i] = 1;
    }
  }

  int Find(int j) {
    if (rootnum[j] == j) {
      return j;
    } else {
      return rootnum[j] = Find(rootnum[j]);
    }
  }

  void Union(int i, int j) {
    int x = Find(i);
    int y = Find(j);
    if (x == y)
      return;
    N--;
    if (rank[x] < rank[y]) {
      rootnum[y] = x;
      unionnum[x] += unionnum[y];
    } else {
      rootnum[x] = y;
      unionnum[y] += unionnum[x];
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  int Num(int j) {
    /*与えられた要素の入っている集合の要素数を答える*/
    int x = Find(j);
    return unionnum[x];
  }

  int UnionNum() {
    /*集合の数を答える*/
    return N;
  }

  ~UnionFindTree() {
    delete rootnum;
    delete rank;
    delete unionnum;
  }
};
int main() {
  int H, W, M;
  cin >> H >> W >> M;
  UnionFindTree utf(M);
  vector<int> cntX(H);
  fill(cntX.begin(), cntX.end(), 0);
  vector<int> cntY(W);
  fill(cntY.begin(), cntY.end(), 0);
  vector<pair<int, int>> t(M);
  for (int i = 0; i < M; i++) {
    cin >> t[i].first >> t[i].second;
    cntX[t[i].first - 1]++;
    cntY[t[i].second - 1]++;
    t[i].first--;
    t[i].second--;
  }
  sort(t.begin(), t.end());
  int ansX = 0;
  int ansY = 0;
  vector<int> xi;
  for (int i = 0; i < H; i++) {
    ansX = max(ansX, cntX[i]);
  }
  for (int i = 0; i < H; i++) {
    if (ansX == cntX[i]) {
      xi.emplace_back(i);
    }
  }

  for (int i = 0; i < W; i++) {
    ansY = max(ansY, cntY[i]);
  }
  vector<int> yi;
  for (int i = 0; i < W; i++) {
    if (ansY == cntY[i]) {
      yi.emplace_back(i);
    }
  }
  for (int i : xi) {
    for (int j : yi) {
      if (find(t.begin(), t.end(), make_pair(i, j)) == t.end()) {
        cout << ansX + ansY << endl;
        return 0;
      }
    }
  }
  cout << ansX + ansY - 1 << endl;
  return 0;
}