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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << ((x)) << endl
#define fi first
#define se second

#define INF 214748360012345

long l[200][200];
long s[200][200];

long dp[2][200];

int main() {
  int n, m;
  while (cin >> n >> m, n | m) {
    fill(l[0], l[n], INF);
    fill(s[0], s[n], INF);
    rep(i, m) {
      int a, b, c;
      char d;
      scanf("%d %d %d %c", &a, &b, &c, &d);
      a--;
      b--;
      if (d == 'L') {
        l[a][b] = c;
        l[b][a] = c;
      } else {
        s[a][b] = c;
        s[b][a] = c;
      }
    }

    rep(i, n) l[i][i] = s[i][i] = 0;
    rep(k, n) rep(i, n) rep(j, n) l[i][j] = min(l[i][j], l[i][k] + l[k][j]);
    rep(k, n) rep(i, n) rep(j, n) s[i][j] = min(s[i][j], s[i][k] + s[k][j]);

    int r;
    cin >> r;
    vector<int> route(r);
    rep(i, r) scanf("%d", &route[i]);
    rep(i, r) route[i]--;

    long *prev = dp[0];
    long *crnt = dp[1];

    fill(prev, prev + n, INF);
    prev[route[0]] = 0;
    rep(i, r - 1) {
      // route[i] -> route[i+1]
      fill(crnt, crnt + n, INF);
      rep(j, n) if (prev[j] != INF) {
        // ??????j??????????????¨?????????????§?
        rep(k, n) crnt[k] = min(crnt[k], prev[j] + l[route[i]][j] + s[j][k] +
                                             l[k][route[i + 1]]);
        crnt[j] = min(crnt[j], prev[j] + l[route[i]][route[i + 1]]);
      }
      swap(crnt, prev);
    }

    cout << *min_element(prev, prev + n) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define mp(a, b) make_pair((a), (b))
#define pb(a) push_back((a))
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << ((x)) << endl
#define fi first
#define se second

#define INF 214748360012345

class UnionFind {
public:
  vector<int> par,
      rank; // parent(negative := its root and abs-value is its size), depth
  UnionFind(int sz) : par(sz, -1), rank(sz, 0) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;                // already belong to same tree
    if (rank[x] < rank[y]) { // y becomes parent node
      par[y] += par[x];
      par[x] = y;
    } else { // x becomes parent node
      par[x] += par[y];
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -par[find(x)]; }
}; // END class UnionFind

struct edge {
  int to;
  long cost;
  char type;
};

typedef pair<long, int> P;

int main() {
  int n, m;
  while (cin >> n >> m, n | m) {
    vector<vector<edge>> vec(n);
    UnionFind uf(n);
    rep(i, m) {
      int a, b, c;
      char d;
      scanf("%d %d %d %c", &a, &b, &c, &d);
      a--;
      b--;
      vec[a].pb((edge{b, c, d}));
      vec[b].pb((edge{a, c, d}));
      if (d == 'L')
        uf.unite(a, b);
    }

    int r;
    cin >> r;
    vector<int> route(r);
    rep(i, r) scanf("%d", &route[i]);
    rep(i, r) route[i]--;

    vector<long> d(n * n, INF);
    d[route[0] * n + route[0]] = 0;
    rep(i, r - 1) {
      // route[i] -> route[i+1]
      // ????????´???*N + ????????´??? ??§??????????????????
      priority_queue<P, vector<P>, greater<P>> pq;
      rep(j, n) {
        int idx = route[i] * n + j;
        if (d[idx] != INF) {
          pq.push(mp(d[idx], idx));
        }
      }
      rep(j, n) if (j != route[i]) rep(k, n) d[j * n + k] = INF;
      // <cost, pos*n + ship>
      while (!pq.empty()) {
        P p = pq.top();
        pq.pop();
        if (p.fi > d[p.se])
          continue;
        int pos = p.se / n;
        if (pos == route[i + 1])
          continue;
        int ship = p.se % n;
        for (auto e : vec[pos]) {
          int nxtp = e.to;
          if (pos != ship && e.type == 'S')
            continue;
          if (e.type == 'L' &&
              !(uf.same(nxtp, route[i + 1]) || uf.same(nxtp, route[i])))
            continue;
          long nxtc = e.cost + p.fi;
          int nxti = nxtp * n;
          if (e.type == 'S')
            nxti += e.to;
          else
            nxti += ship;
          if (nxtc < d[nxti]) {
            d[nxti] = nxtc;
            pq.push(mp(nxtc, nxti));
          }
        }
      }
    }
    long res = INF;
    for (int i = route[r - 1] * n; i < route[r - 1] * n + n; i++)
      res = min(res, d[i]);
    cout << res << endl;
  }
  return 0;
}