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

#include <bits/stdc++.h>

#define rep(n) for (int i = 0; i < n; i++)
#define repp(j, n) for (int j = 0; j < n; j++)
#define reppp(i, m, n) for (int i = m; i < n; i++)
#define all(c) c.begin(), c.end()
#define rall(c) c.rbegin(), c.rend()
#define debug(x) cerr << #x << ": " << x << endl

using namespace std;

typedef long long ll;
typedef pair<ll, ll> Pll;
typedef pair<int, int> Pii;
struct Edge {
  int from, to;
  ll cost;
};

const ll MOD = 1000000007;
const long double EPS = 10e-10;
const ll INF = 1LL << 50;

int main() {
  int n, m, x, y, r;
  ll t;
  char sl;
  while (scanf("%d%d", &n, &m), n) {
    vector<vector<ll>> st(n, vector<ll>(n, INF)), lt(n, vector<ll>(n, INF));
    rep(n) {
      st[i][i] = 0LL;
      lt[i][i] = 0LL;
    }
    rep(m) {
      cin >> x >> y >> t >> sl;
      x--;
      y--;
      if (sl == 'S') {
        st[x][y] = st[y][x] = min(st[x][y], t);
      } else {
        lt[x][y] = lt[y][x] = min(lt[x][y], t);
      }
    }

    repp(k, n) {
      repp(i, n) {
        repp(j, n) {
          st[i][j] = min(st[i][j], st[i][k] + st[k][j]);
          lt[i][j] = min(lt[i][j], lt[i][k] + lt[k][j]);
        }
      }
    }

    cin >> r;
    vector<int> z(r);
    rep(r) {
      cin >> z[i];
      z[i]--;
    }

    // dp[i][j]: z[i]にいる，お船はjにあるときの最短時間
    ll dp[r][n];
    fill(dp[0], dp[r], INF);
    dp[0][z[0]] = 0LL;
    rep(r - 1) {
      // z[i]からkまで徒歩，kからlまで船，lからz[i+1]まで徒歩
      repp(k, n) {
        if (dp[i][k] >= INF || lt[z[i]][k] >= INF)
          continue;
        repp(l, n) {
          dp[i + 1][l] = min(dp[i + 1][l], dp[i][k] + lt[z[i]][k] + st[k][l] +
                                               lt[l][z[i + 1]]);
        }
        if (lt[z[i]][z[i + 1]] < INF)
          dp[i + 1][k] = min(dp[i + 1][k], dp[i][k] + lt[z[i]][z[i + 1]]);
      }
    }

    ll ans = INF;
    rep(n) ans = min(ans, dp[r - 1][i]);
    cout << ans << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define rep(n) for (int i = 0; i < n; i++)
#define repp(j, n) for (int j = 0; j < n; j++)
#define reppp(i, m, n) for (int i = m; i < n; i++)
#define all(c) c.begin(), c.end()
#define rall(c) c.rbegin(), c.rend()
#define debug(x) cerr << #x << ": " << x << endl

using namespace std;

typedef long long ll;
typedef pair<ll, ll> Pll;
typedef pair<int, int> Pii;
struct Edge {
  int from, to;
  ll cost;
};

const ll MOD = 1000000007;
const long double EPS = 10e-10;

int main() {
  int n, m, x, y, r;
  ll t;
  char sl;
  while (scanf("%d%d", &n, &m) && n != 0) {
    vector<vector<ll>> st(n, vector<ll>(n, LLONG_MAX)),
        lt(n, vector<ll>(n, LLONG_MAX));
    rep(n) {
      st[i][i] = 0LL;
      lt[i][i] = 0LL;
    }
    rep(m) {
      cin >> x >> y >> t >> sl;
      x--;
      y--;
      if (sl == 'S') {
        st[x][y] = min(st[x][y], t);
        st[y][x] = min(st[y][x], t);
      } else {
        lt[x][y] = min(lt[x][y], t);
        lt[y][x] = min(lt[y][x], t);
      }
    }

    repp(k, n) {
      repp(i, n) {
        repp(j, n) {
          if (st[i][k] != LLONG_MAX && st[k][j] != LLONG_MAX)
            st[i][j] = min(st[i][j], st[i][k] + st[k][j]);
          if (lt[i][k] != LLONG_MAX && lt[k][j] != LLONG_MAX)
            lt[i][j] = min(lt[i][j], lt[i][k] + lt[k][j]);
        }
      }
    }

    cin >> r;
    vector<int> z(r);
    rep(r) {
      cin >> z[i];
      z[i]--;
    }

    // dp[i][j]: z[i]にいる，お船はjにあるときの最短時間
    ll dp[r][n];
    fill(dp[0], dp[r], LLONG_MAX);
    dp[0][0] = 0LL;
    rep(r - 1) {
      repp(j, n) {
        if (dp[i][j] == LLONG_MAX)
          continue;
        // z[i]からkまで徒歩，kからlまで船，lからz[i+1]まで徒歩
        repp(k, n) {
          if (lt[z[i]][k] == LLONG_MAX)
            continue;
          repp(l, n) {
            if (dp[i][k] != LLONG_MAX && st[k][l] != LLONG_MAX &&
                lt[l][z[i + 1]] != LLONG_MAX) {
              dp[i + 1][l] = min(dp[i + 1][l], dp[i][k] + lt[z[i]][k] +
                                                   st[k][l] + lt[l][z[i + 1]]);
            }
          }
        }
        // 徒歩だけで行く
        if (lt[z[i]][z[i + 1]] != LLONG_MAX) {
          dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + lt[z[i]][z[i + 1]]);
        }
      }
      // repp(j, n) printf("%5lld", dp[z[i+1]][j] == LLONG_MAX ? -1 :
      // dp[z[i+1]][j]); printf("\\n");
    }

    ll ans = LLONG_MAX;
    rep(n) ans = min(ans, dp[r - 1][i]);
    cout << ans << endl;
  }
}