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

#include <cstdio>
#include <iostream>
// #include <cstdlib>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
// #include <limits>
#include <sstream>
// #include <functional>
using namespace std;

#define len(array) (sizeof(array) / sizeof *(array))
#define rep(i, s, e) for (int i = s; i < e; i++)
#define rrep(i, e, s) for (int i = e; s <= i; i--)
#define vrange(v) v.begin(), v.end()
#define vrrange(v) v.rbegin(), v.rend()
#define vsort(v) sort(vrange(v))
#define vrsort(v) sort(vrrange(v))
#define arange(a) a, a + len(a)
#define asort(a) sort(arange(a))
#define arsort(a, t) sort(arange(a), greater<t>())
#define afill(a, v) fill(arange(a), v)
#define afill2(a, v, t) fill((t *)a, (t *)(a + len(a)), v)
#define fmax(a, b) (a < b ? b : a)
#define fmin(a, b) (a > b ? b : a)
#define fabs(a) (a < 0 ? -a : a)
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<string, int> P;
typedef pair<int, int> P2;
const int INF = (int)1e9;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-10;
// const int dx[] = {1, -1, 0, 0, 1, -1, -1, 1};
// const int dy[] = {0, 0, 1, -1, -1, -1, 1, 1};
// const int weight[] = {0,1,10,100,1000,10000,100000,1000000,10000000};
// priority_queue<int, vector<int>, greater<int>> q;

vector<P> edge[41];
int n, a, s, g, x, y;

void doIt() {
  string ss, costs[2][41];
  // int nums[41];
  int now, prev;
  bool bOK;
  int mxlen;
  const string inf = "INF";
  while (true) {
    cin >> n >> a >> s >> g;
    if (n + a + s + g == 0)
      break;
    mxlen = 0;
    rep(i, 0, a) {
      cin >> x >> y >> ss;
      // 逆に辿る
      edge[y].push_back(P(ss, x));
      mxlen = fmax(mxlen, ss.length());
    }
    // rep(i, 0, n) vsort(edge[i]);
    // Bermann-Ford
    now = 0;
    prev = 1;
    afill2(costs, inf, string);
    // afill(nums, 0);
    costs[prev][g] = costs[now][g] = "";
    bOK = true;
    rep(k, 0, (mxlen + 1) * n + 2) {
      rep(i, 0, n) {
        if (costs[prev][i] != inf) {
          rep(j, 0, edge[i].size()) {
            P e = edge[i][j];
            if (costs[now][e.second] == inf ||
                e.first + costs[prev][i] < costs[now][e.second]) {
              // cout << "bef : " << costs[now][e.second] << endl;
              costs[now][e.second] = e.first + costs[prev][i];
              // cout << "aft : " <<  costs[now][e.second] << endl;
              if (e.second == s && n <= k) {
                bOK = false;
                break;
              }
            }
          }
        }
      }
      rep(i, 0, n) { costs[prev][i] = costs[now][i]; }
      prev = 1 - prev;
      now = 1 - now;
    }
    if (bOK && costs[now][s] != inf)
      cout << costs[now][s] << endl;
    else
      cout << "NO" << endl;
    rep(i, 0, n) edge[i].clear();
  }
}

int main() {
  doIt();
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
// #include <cstdlib>
#include <algorithm>
#include <cmath>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
// #include <limits>
#include <sstream>
// #include <functional>
using namespace std;

#define len(array) (sizeof(array) / sizeof *(array))
#define rep(i, s, e) for (int i = s; i < e; i++)
#define rrep(i, e, s) for (int i = e; s <= i; i--)
#define vrange(v) v.begin(), v.end()
#define vrrange(v) v.rbegin(), v.rend()
#define vsort(v) sort(vrange(v))
#define vrsort(v) sort(vrrange(v))
#define arange(a) a, a + len(a)
#define asort(a) sort(arange(a))
#define arsort(a, t) sort(arange(a), greater<t>())
#define afill(a, v) fill(arange(a), v)
#define afill2(a, v, t) fill((t *)a, (t *)(a + len(a)), v)
#define fmax(a, b) (a < b ? b : a)
#define fmin(a, b) (a > b ? b : a)
#define fabs(a) (a < 0 ? -a : a)
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<string, int> P;
typedef pair<int, int> P2;
const int INF = (int)1e9;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-10;
// const int dx[] = {1, -1, 0, 0, 1, -1, -1, 1};
// const int dy[] = {0, 0, 1, -1, -1, -1, 1, 1};
// const int weight[] = {0,1,10,100,1000,10000,100000,1000000,10000000};
// priority_queue<int, vector<int>, greater<int>> q;

vector<P> edge[41];
bool used[41];
int n, a, s, g, x, y, back[41];
string sback[41], goal, sans;

bool rec(int node) {
  int e, pos;
  bool ret = false;
  string str;
  if (node == g) {
    vector<string> v;
    pos = g;
    while (pos != s) {
      // printf("pos = %d\\n", pos);
      // cout << sback[pos] << endl;
      v.push_back(sback[pos]);
      pos = back[pos];
    }
    str = "";
    rrep(i, v.size() - 1, 0) str += v[i];
    if (sans == "" || str < sans) {
      sans = str;
    }
    return true;
  }
  if (!used[node]) {
    used[node] = true;
    rep(i, 0, edge[node].size()) {
      if (i == 0 || str == edge[node][i].first) {
        e = edge[node][i].second;
        back[e] = node;
        sback[e] = edge[node][i].first;
        str = sback[e];
        // cout << "e = " << e << ", se = " << sback[e] << endl;
        if (rec(e)) {
          ret = true;
        }
        back[e] = -1;
      } else
        break;
    }
    used[node] = false;
  }
  return ret;
}

bool verify(int node, int len) {
  int e, res;
  string se;
  if (goal.length() <= len) {
    return true;
  }
  rep(i, 0, edge[node].size()) {
    e = edge[node][i].second;
    se = edge[node][i].first;
    res = goal.compare(len, se.length(), se);
    if (res == 0) {
      if (!verify(e, len + se.length())) {
        return false;
      }
    } else if (0 < res) {
      return false;
    }
  }
  return true;
}

void doIt() {
  string ss;
  while (true) {
    cin >> n >> a >> s >> g;
    if (n + a + s + g == 0)
      break;
    rep(i, 0, a) {
      cin >> x >> y >> ss;
      edge[x].push_back(P(ss, y));
    }
    rep(i, 0, n) vsort(edge[i]);
    afill(used, false);
    afill(back, -1);
    sans = "";
    // afill(sback, "");
    if (rec(s)) {
      vector<string> v;
      int pos = g;
      goal = sans;
      // 本当に最小か確認
      if (verify(s, 0))
        cout << goal << endl;
      else
        cout << "NO" << endl;
    } else
      cout << "NO" << endl;
    rep(i, 0, n) edge[i].clear();
  }
}

int main() {
  doIt();
  return 0;
}