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

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct edge {
  int x, y;
  string s;
};

string solve(int n, int s, int g, const vector<edge> &E) {
  vector<string> d(n + 1, "~");
  d[g].clear();
  string t;

  bool updated = true;
  for (int i = 0; i < n * n + 3 && updated; ++i) {
    updated = false;
    for (int j = 0; j < E.size(); ++j) {
      if (d[E[j].y][0] != '~') {
        t = E[j].s + d[E[j].y];
        if (d[E[j].x] > t) {
          d[E[j].x] = t;
          updated = true;

          if (E[j].x == s && i >= n) {
            return "NO";
          }
        }
      }
    }
  }

  if (d[s][0] == '~') {
    return "NO";
  }
  return d[s];
}

int main() {
  int n, a, s, g, x, y;
  while (cin >> n >> a >> s >> g, n) {
    vector<edge> E(a);
    for (int i = 0; i < a; ++i) {
      cin >> E[i].x >> E[i].y >> E[i].s;
    }
    cout << solve(n, s, g, E) << '\\n';
  }
}

Error: TLE

Fixed submission:


#include <algorithm>
#include <bitset>
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>

#include <cstdio>

using namespace std;

typedef pair<string, int> spell;

inline int cmp(const string &s1, const string &s2) {
  return s1.compare(0, s1.length(), s2, 0, s1.length());
}

string str;
bitset<150> able;
bool pr1(const spell &sp) { return !able[sp.second]; }
bool pr2(const spell &sp) { return cmp(str, sp.first) != 0; }

struct spellbit {
  int pos;
  string sp;
  bitset<150> bit;
  spellbit(int a, const string &s, bitset<150> b = bitset<150>())
      : pos(a), sp(s), bit(b) {
    bit.set(a);
  }

  bool operator()(const spellbit &spb1, const spellbit &spb2) {
    return cmp(spb1.sp, spb2.sp) < 0;
  }
} compobj(0, "");

int main() {
  int n, a, s, g, x, y;
  for (; cin >> n >> a >> s >> g, n; able.reset()) {
    vector<list<spell>> vec(n);
    vector<vector<int>> vec_b(n);
    for (int i = 0; i < a; i++) {
      cin >> x >> y >> str;

      vec[x].push_back(spell(str, y));
      vec_b[y].push_back(x);
    }
    stack<int> st;
    for (st.push(g); !st.empty();) {
      int p = st.top();
      st.pop();
      able[p] = true;
      for (vector<int>::iterator it = vec_b[p].begin(); it != vec_b[p].end();
           ++it) {
        if (!able[*it])
          st.push(*it);
      }
    }
    vec_b.clear();

    if (!able[s]) {
      cout << "NO\\n";
      continue;
    }

    for (int i = 0; i < n; i++) {
      vec[i].remove_if(pr1);
      if (!vec[i].empty()) {
        vec[i].sort();
        str = vec[i].front().first;
        vec[i].remove_if(pr2);
      }
    }

    string best = "~";

    vector<spellbit> v1, v2;
    v1.push_back(spellbit(s, ""));

    for (; !v1.empty();) {
      str = v1.front().sp;
      if (str >= best)
        break;

      for (vector<spellbit>::iterator it1 = v1.begin(); it1 != v1.end();
           ++it1) {
        for (list<spell>::iterator it2 = vec[it1->pos].begin();
             it2 != vec[it1->pos].end(); ++it2) {
          string newst = it1->sp + it2->first;
          if (it2->second == g) {
            if (newst < best)
              best = newst;
          } else if (!it1->bit[it2->second]) {
            v2.push_back(spellbit(it2->second, newst, it1->bit));
          }
        }
      }

      v1.swap(v2);
      v2.clear();
      sort(v1.begin(), v1.end(), compobj);
    }

    if (best == "~") {
      cout << "NO\\n";
    } else {
      cout << best << '\\n';
    }
  }
}