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

#include <bits/stdc++.h>
using namespace std;

vector<int> seat;
vector<bool> fix;
int Ns;
vector<int> movex = {0, 0, -1, 1};
vector<int> movey = {-1, 1, 0, 0};

void optimize(int);

int main() {
  int N;
  cin >> N;
  Ns = N + 2;
  int MN = N * N;
  int MN2 = (N + 2) * (N + 2);
  seat = vector<int>(MN2);
  fix = vector<bool>(MN2, true);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      seat.at((i + 1) * Ns + j + 1) = min(min(i, N - i - 1), min(j, N - j - 1));
    }
  }

  int hate = 0;
  int next;

  for (int i = 0; i < MN; i++) {
    cin >> next;
    next--;
    next = ((next / N) + 1) * Ns + (next % N) + 1;

    hate += seat.at(next);
    fix.at(next) = false;
    optimize(next);
  }

  cout << hate << endl;
}

void optimize(int N) {
  int hit = seat.at(N) + fix.at(N);
  for (int i = 0; i < 4; i++) {
    int around = movey.at(i) * Ns + movex.at(i) + N;
    if (seat.at(around) > hit) {
      seat.at(around) = hit;
      optimize(around);
    }
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
struct ufind {
  vector<int> uf;
  ufind(int q) {
    uf = vector<int>(q);
    for (int i = 0; i < q; i++)
      uf.at(i) = i;
  }

  ufind(vector<int> q) { uf = q; }

  void stick(int a, int b) {
    if (a == b)
      return;
    a = fpe(a);
    b = fpe(b);
    int minx = (a < b) ? a : b;
    uf.at(a) = minx;
    uf.at(b) = minx;
  }

  int fpe(int a) { return (uf.at(a) == a) ? a : uf.at(a) = fpe(uf.at(a)); }

  bool find(int a, int b) {
    if (a == b)
      return true;
    return fpe(a) == fpe(b);
  }
};

int main() {
  int N;
  cin >> N;
  vector<vector<int>> seat(N + 2, vector<int>(N + 2));
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= N; j++) {
      seat.at(i).at(j) = 1;
    }
  }
  int S = N + 2;
  // ufind uf(S*S);
  int NN = N * N;
  int outseat;
  int hate = 0;

  while (NN) {

    cin >> outseat;
    int sx = (outseat - 1) % N + 1;
    int sy = ((outseat - 1) / N) + 1;

    ufind M(S * S);
    auto Mseat = seat;
    Mseat.at(sy).at(sx) = 0;
    int cucu = sy * S + sx;

    while (true) {

      for (int i = 0; i < S; i++) {
        for (int j = 0; j < S; j++) {

          // 縦

          if (i && (!Mseat.at(i - 1).at(j) && !Mseat.at(i).at(j))) {
            M.stick((i - 1) * S + j, i * S + j);
          }

          // 横
          if (j && (!Mseat.at(i).at(j - 1) && !Mseat.at(i).at(j))) {
            M.stick(i * S + j - 1, i * S + j);
          }
        }
      }

      M.uf.at(cucu) = M.fpe(cucu);

      if (!M.uf.at(cucu))
        break;

      for (int i = 0; i < S; i++) {
        for (int j = 0; j < S; j++) {

          int Mroot = M.uf.at(cucu);
          int current = i * S + j;
          // 縦
          if (i &&
              (M.fpe((i - 1) * S + j) == Mroot || M.fpe(current) == Mroot)) {
            Mseat.at(i - 1).at(j) = 0;
            Mseat.at(i).at(j) = 0;
          }

          // 横
          if (j && (M.fpe(current - 1) == Mroot || M.fpe(current) == Mroot)) {
            Mseat.at(i).at(j - 1) = 0;
            Mseat.at(i).at(j) = 0;
          }
        }
      }

      hate++;
    }

    seat.at(sy).at(sx) = 0;

    NN--;
  }

  cout << hate << endl;
}