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

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, n) for (int i = (a); i < (n); i++)
using namespace std;

bool p[1 << 10][10]; // lock, nextorder
bool used[1 << 10][10];
int N;
string s;

struct State {
  int lock, nextorder;
};
int main() {
  while (cin >> N, N) {
    cin >> s;
    s = 'u' + s;
    N++;
    int Lock = 0;
    int nextOrder;
    bool deadLock = false;
    // single thread
    REP(i, N) {
      if (s[i] == 'u' && s[i + 1] == 'u')
        continue;
      int nowOrder = s[i] - '0';
      if (isdigit(s[i])) {
        if (Lock & (1 << nowOrder)) {
          deadLock = true;
          break;
        }
        Lock |= (1 << (nowOrder));
      } else {
        Lock = 0;
      }
      if (i + 1 < N && isdigit(s[i + 1])) {
        nextOrder = s[i + 1] - '0';
        p[Lock][nextOrder] = true;
      }
    }
    // multi thread
    REP(lock_s, 1 << 10) {
      if (deadLock)
        break;
      REP(next_s, 10) {
        if (!p[lock_s][next_s])
          continue;
        queue<State> que;
        que.push({lock_s, next_s});
        while (!que.empty()) {
          State state = que.front();
          que.pop();
          int lock_i = state.lock;
          int next_i = state.nextorder;
          REP(lock_j, 1 << 10) {
            if (lock_i & lock_j)
              continue;
            REP(next_j, 10) {
              if (!p[lock_j][next_j])
                continue;
              int locks = lock_i | lock_j;
              if ((1 << next_i) & lock_j && (1 << next_j) & lock_i) {
                deadLock = true;
                break;
              }
              if ((lock_j & (1 << next_i)) && !used[locks][next_j]) {
                que.push({locks, next_j});
                used[locks][next_j] = true;
              }
              if ((lock_i & (1 << next_j)) && !used[locks][next_i]) {
                que.push({locks, next_i});
                used[locks][next_i] = true;
              }
            }
            if (deadLock)
              break;
          }
          if (deadLock)
            break;
        }
        if (deadLock)
          break;
      }
    }
    if (deadLock) {
      cout << "UNSAFE" << endl;
    } else {
      cout << "SAFE" << endl;
    }
    fill(p[0], p[1 << 10], false);
    fill(used[0], used[1 << 10], false);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (n); i++)

using namespace std;

int nextO[10];
int have_lock[10];
int N;
string s;
vector<string> ss;

void split() {
  ss.clear();
  int l = 0;
  REP(i, N) {
    if (s[i] == 'u') {
      ss.push_back(s.substr(l, i - l));
      l = i + 1;
    }
  }
}

bool res = false;
bool dfs(int thread_i, int end_i) {
  if (thread_i > 9) {
    return false;
  }
  for (int st_i = 0; st_i < end_i; st_i++) {
    string st = ss[st_i];
    have_lock[thread_i] = 0;
    nextO[thread_i] = 1 << (st[0] - '0');
    bool already_used = false;
    REP(i, thread_i) {
      if (have_lock[i] & (1 << (st[0] - '0'))) {
        already_used = true;
        break;
      }
    }
    if (already_used)
      continue;
    for (int s_i = 0; s_i < st.size(); s_i++) {
      bool already_used = false;
      REP(i, thread_i + 1) {
        if (have_lock[i] & (1 << (st[s_i] - '0'))) {
          already_used = true;
          break;
        }
      }
      if (already_used) { //?????¢???
        REP(i, thread_i + 1) {
          if (have_lock[thread_i] & nextO[i]) {
            return true;
          }
        }
      } else { //???????????????,??????????????????
        have_lock[thread_i] |= 1 << (st[s_i] - '0');
      }
      if (s_i + 1 < st.size() && st[s_i + 1] != 'u') {
        nextO[thread_i] = (1 << (st[s_i + 1] - '0'));
      } else {
        nextO[thread_i] = 0;
      }
      res |= dfs(thread_i + 1, st_i + 1);
      if (res || already_used)
        break;
    }
    if (res)
      break;
  }
  have_lock[thread_i] = 0;
  nextO[thread_i] = 0;
  return res;
}

int main() {

  while (cin >> N, N) {
    cin >> s;
    split();
    res = false;
    cout << (dfs(0, ss.size()) ? "UNSAFE" : "SAFE") << endl;
  }
  return 0;
}