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

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define DEBUG(x) cerr << #x << " = " << x << endl
vector<string> parse(const string &s) {
  vector<string> ret;
  string buf;
  REP(i, s.size()) {
    if (s[i] == 'u') {
      ret.push_back(buf);
      buf.clear();
    } else {
      buf += s[i];
    }
  }
  return ret;
}
vector<pair<int, int>> toStates(const vector<string> &ops) {
  vector<pair<int, int>> states;
  for (const string &op : ops) {
    // DEBUG(op);
    int locked = 0;
    for (char c : op) {
      states.emplace_back(locked, c - '0');
      locked |= (1 << (c - '0'));
    }
  }
  return states;
}
bool contains(int A, int B) {
  // A contains B
  while (B > 0) {
    if (B & 1) {
      if ((A & 1) == 0)
        return false;
    }
    A >>= 1;
    B >>= 1;
  }
  return true;
}
bool dp[1 << 10][10];
signed main() {
  ios::sync_with_stdio(false);
  while (true) {
    int N;
    cin >> N;
    if (N == 0)
      break;
    string T;
    cin >> T;
    vector<string> ops = parse(T);
    vector<pair<int, int>> states = toStates(ops);
    memset(dp, 0, sizeof(dp));
    bool unsafe = false;
    queue<pair<int, int>> que;
    for (const auto &p : states) {
      if ((p.first >> p.second) & 1)
        unsafe = true;
      que.emplace(p);
      dp[p.first][p.second] = true;
    }
    while (!que.empty()) {
      auto p = que.front();
      que.pop();
      for (int S = 0; S < (1 << 10); ++S) {
        for (int next = 0; next < 10; ++next) {
          if (dp[S][next] == false)
            continue;
          auto q = make_pair(S, next);
          if ((p.first & q.first) != 0)
            continue;
          if ((p.first >> q.second) & 1 &&
              dp[p.first | q.first][p.second] == false) {
            dp[p.first | q.first][p.second] = true;
            que.emplace(p.first | q.first, p.second);
          }
          if ((q.first >> p.second) & 1 &&
              dp[p.first | q.first][q.second] == false) {
            dp[p.first | q.first][q.second] = true;
            que.emplace(p.first | q.first, q.second);
          }
        }
      }
    }
    REP(S1, 1 << 10) {
      REP(n1, 10) {
        if (dp[S1][n1] == false)
          continue;
#if 0
        if(dp[S1][n1]) {
          cerr << "[";
          REP(i,10) {
            if((S1 >> i) & 1) cerr << i;
          }
          cerr << "] " << n1 << endl;
        }
#endif
        REP(S2, 1 << 10) {
          REP(n2, 10) {
            if ((S1 & S2) == 0 && dp[S1][n1] && dp[S2][n2]) {
              if ((S1 >> n2) & 1 && (S2 >> n1) & 1) {
                unsafe = true;
              }
            }
          }
        }
      }
    }
    cout << (unsafe ? "UNSAFE" : "SAFE") << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define DEBUG(x) cerr << #x << " = " << x << endl
vector<string> parse(const string &s) {
  vector<string> ret;
  string buf;
  REP(i, s.size()) {
    if (s[i] == 'u') {
      ret.push_back(buf);
      buf.clear();
    } else {
      buf += s[i];
    }
  }
  return ret;
}
vector<pair<int, int>> toStates(const vector<string> &ops) {
  vector<pair<int, int>> states;
  for (const string &op : ops) {
    // DEBUG(op);
    int locked = 0;
    for (char c : op) {
      states.emplace_back(locked, c - '0');
      locked |= (1 << (c - '0'));
    }
  }
  return states;
}
bool contains(int A, int B) {
  // A contains B
  while (B > 0) {
    if (B & 1) {
      if ((A & 1) == 0)
        return false;
    }
    A >>= 1;
    B >>= 1;
  }
  return true;
}
bool dp[1 << 10][10];
signed main() {
  ios::sync_with_stdio(false);
  while (true) {
    int N;
    cin >> N;
    if (N == 0)
      break;
    string T;
    cin >> T;
    vector<string> ops = parse(T);
    vector<pair<int, int>> states = toStates(ops);
    memset(dp, 0, sizeof(dp));
    bool unsafe = false;
    queue<pair<int, int>> que;
    for (const auto &p : states) {
      if ((p.first >> p.second) & 1)
        unsafe = true;
      que.emplace(p);
      dp[p.first][p.second] = true;
    }
    while (!que.empty()) {
      auto p = que.front();
      que.pop();
      for (int S = 0; S < (1 << 10); ++S) {
        for (int next = 0; next < 10; ++next) {
          if (dp[S][next] == false)
            continue;
          auto q = make_pair(S, next);
          if ((p.first & q.first) != 0)
            continue;
          if ((p.first >> q.second) & 1 &&
              dp[p.first | q.first][p.second] == false) {
            dp[p.first | q.first][p.second] = true;
            que.emplace(p.first | q.first, p.second);
          }
          if ((q.first >> p.second) & 1 &&
              dp[p.first | q.first][q.second] == false) {
            dp[p.first | q.first][q.second] = true;
            que.emplace(p.first | q.first, q.second);
          }
        }
      }
    }
    REP(S1, 1 << 10) {
      REP(n1, 10) {
#if 0
        if(dp[S1][n1]) {
          cerr << "[";
          REP(i,10) {
            if((S1 >> i) & 1) cerr << i;
          }
          cerr << "] " << n1 << endl;
        }
#endif
        REP(S2, 1 << 10) {
          REP(n2, 10) {
            if ((S1 & S2) == 0 && dp[S1][n1] && dp[S2][n2]) {
              if ((S1 >> n2) & 1 && (S2 >> n1) & 1) {
                unsafe = true;
              }
            }
          }
        }
      }
    }
    cout << (unsafe ? "UNSAFE" : "SAFE") << endl;
  }
}