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

#include <bitset>
#include <iostream>
#include <set>
#include <vector>
using namespace std;

vector<pair<int, int>> locks;
set<pair<int, int>> check;

int product(int l, int r) { return l & r; }

int set_union(int l, int r) { return l | r; }

int bit(char x) { return (x - '0'); }

int main() {
  while (1) {
    int n;
    cin >> n;
    if (!n)
      break;
    locks.clear();
    check.clear();
    string s;
    cin >> s;
    int lock = 0;
    int xflag = 0;
    for (int i = 0; i < s.size(); i++) {
      if (s[i] == 'u') {
        lock = 0;
        continue;
      }
      pair<int, int> p = make_pair(lock, bit(s[i]));
      if (check.find(p) == check.end()) {
        locks.push_back(p);
        check.insert(p);
      }
      //      cout << static_cast<std::bitset<10> >(lock)<< endl;
      if (lock & 1 << bit(s[i])) {
        xflag = 1;
        break;
      }
      lock |= 1 << bit(s[i]);
    }

    if (xflag) {
      cout << "UNSAFE\\n";
    } else {

      while (1) {
        //      cout << "x\\n";
        int flag = 0;
        for (int i = 0; i < locks.size(); i++) {
          pair<int, int> l = locks[i];
          //	cout << i << endl;
          for (int j = i + 1; j < locks.size(); j++) {
            pair<int, int> r = locks[j];
            int x = set_union(l.first, r.first);
            pair<int, int> p = make_pair(x, r.second);
            if (!product(l.first, r.first) && !(l.first & 1 << r.second) &&
                r.first & 1 << l.second && check.find(p) == check.end()) {
              //	    for(set<char>::iterator it = l.first.begin(); it !=
              //l.first.end(); it++) cout << *it; 	    for(set<char>::iterator it =
              //r.first.begin(); it != r.first.end(); it++) cout << *it; cout <<
              //endl;
              // for(set<char>::iterator it = x.begin(); it != x.end(); it++)
              // cout << *it; cout << endl;
              //	    cout << "-------------------\\n";
              locks.push_back(p);
              check.insert(p);
              flag = 1;
            }
          }
        }
        if (!flag)
          break;
      }
      //    cout << "----\\n";
      int flag = 0;
      for (int i = 0; i < locks.size(); i++) {
        pair<int, int> l = locks[i];
        //      cout << static_cast<std::bitset<10> >(l.first) << " " <<
        //      l.second<< endl;
        for (int j = i + 1; j < locks.size(); j++) {
          pair<int, int> r = locks[j];
          if (!product(l.first, r.first) && l.first & 1 << r.second &&
              r.first & 1 << l.second) {
            cout << "UNSAFE\\n";
            flag = 1;
            i = locks.size();
            break;
          }
        }
      }
      if (!flag)
        cout << "SAFE\\n";
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <set>
#include <vector>
using namespace std;

vector<pair<set<char>, int>> locks;
set<set<char>> check;

set<char> product(set<char> &l, set<char> &r) {
  set<char> ret;
  for (set<char>::iterator it = l.begin(); it != l.end(); it++)
    if (r.find(*it) != r.end())
      ret.insert(*it);
  return ret;
}

set<char> set_union(set<char> &l, set<char> &r) {
  set<char> ret;
  for (set<char>::iterator it = l.begin(); it != l.end(); it++)
    ret.insert(*it);
  for (set<char>::iterator it = r.begin(); it != r.end(); it++)
    ret.insert(*it);
  return ret;
}

int main() {
  while (1) {
    int n;
    cin >> n;
    if (!n)
      break;
    locks.clear();
    check.clear();
    string s;
    cin >> s;
    set<char> lock;
    int xflag = 0;
    for (int i = 0; i < s.size(); i++) {
      if (s[i] == 'u') {
        lock.clear();
        continue;
      }
      locks.push_back(make_pair(lock, s[i]));
      check.insert(lock);
      if (lock.find(s[i]) != lock.end()) {
        xflag = 1;
        break;
      }
      lock.insert(s[i]);
    }

    if (xflag) {
      cout << "UNSAFE\\n";
    } else {

      while (1) {

        int flag = 0;
        for (int i = 0; i < locks.size(); i++) {
          pair<set<char>, int> l = locks[i];
          for (int j = i + 1; j < locks.size(); j++) {
            //	  cout << i << endl;
            pair<set<char>, int> r = locks[j];
            if (product(l.first, r.first).size() == 0 &&
                l.first.find(r.second) == l.first.end() &&
                r.first.find(l.second) != r.first.end() &&
                check.find(set_union(l.first, r.first)) == check.end()) {
              //	    for(set<char>::iterator it = l.first.begin(); it !=
              //l.first.end(); it++) cout << *it; 	    for(set<char>::iterator it =
              //r.first.begin(); it != r.first.end(); it++) cout << *it; cout <<
              //endl;
              set<char> x = set_union(l.first, r.first);
              //	    for(set<char>::iterator it = x.begin(); it !=
              //x.end(); it++) cout << *it; cout << endl; 	    cout <<
              //"-------------------\\n";
              locks.push_back(make_pair(set_union(l.first, r.first), r.second));
              check.insert(set_union(l.first, r.first));
              flag = 1;
            }
          }
        }
        if (!flag)
          break;
      }

      int flag = 0;
      for (int i = 0; i < locks.size(); i++) {
        pair<set<char>, int> l = locks[i];
        //      for(set<char>::iterator it = l.first.begin(); it !=
        //      l.first.end(); it++) cout << *it; cout << endl;
        for (int j = i + 1; j < locks.size(); j++) {
          pair<set<char>, int> r = locks[j];
          if (product(l.first, r.first).size() == 0 &&
              l.first.find(r.second) != l.first.end() &&
              r.first.find(l.second) != r.first.end()) {
            cout << "UNSAFE\\n";
            flag = 1;
            i = locks.size();
            break;
          }
        }
      }
      if (!flag)
        cout << "SAFE\\n";
    }
  }
  return 0;
}