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

/*#include <cstdio>
#include <algorithm>
#include <limits>
#include <queue>
#include <utility>
#include <vector>
#define rep(i,a) for(int i=0;i<(a);++i)

constexpr int MAX_N = 200, MAX_R = 1000, INF =
std::numeric_limits<int>::max()>>2;

struct edge
{
  int to, cost;
  bool ship;

  edge( int to, int cost, bool ship )
  : to(to), cost(cost), ship(ship)
  {}
};

struct State
{
  int dist, v, ord, shipP;

  State( int dist, int v, int ord, int shipP )
  : dist(dist), v(v), ord(ord), shipP(shipP)
  {}

  bool operator< ( const State &s ) const
  { return this->dist > s.dist; }
};

int N, M;
std::vector<edge> G[MAX_N];
int R;
int z[MAX_R];
short dp[MAX_N][MAX_R][MAX_N];

int main()
{
  while( scanf( "%d%d", &N, &M ), N|M )
  {
    rep( i, N )
      G[i].clear();

    rep( i, M )
    {
      int x, y, t;
      char sl;
      scanf( "%d%d%d %c", &x, &y, &t, &sl );
      --x; --y;
      //putchar(sl);
      G[x].push_back( edge( y, t, sl=='S' ) );
      G[y].push_back( edge( x, t, sl=='S' ) );
    }

    scanf( "%d", &R );
    rep( i, R )
      scanf( "%d", z+i ), --z[i];

    std::priority_queue<State> pque;
    pque.push( State( 0, z[0], 0, 0 ) );
    std::fill( (int*)dp, (int*)(dp+N), INF );
    dp[z[0]][0][0] = 0;

    while( !pque.empty() )
    {
      State st = pque.top(); pque.pop();

      if( st.dist > dp[st.v][st.ord][st.shipP] || st.ord == R-1 )
        continue;

      //printf( "[%d %d %d %d]\\n", st.dist, st.v, st.ord, st.shipP );

      for( auto e : G[st.v] )
      {
        int nord = e.to == z[st.ord+1] ? st.ord+1 : st.ord;

        if( st.shipP == st.v && e.ship && dp[e.to][nord][e.to] >
dp[st.v][st.ord][st.shipP]+e.cost )
        {
          dp[e.to][nord][e.to] = dp[st.v][st.ord][st.shipP]+e.cost;
          pque.push( State( dp[e.to][nord][e.to], e.to, nord, e.to ) );
        }

        if( !e.ship && dp[e.to][nord][st.shipP] >
dp[st.v][st.ord][st.shipP]+e.cost )
        {
          dp[e.to][nord][st.shipP] = dp[st.v][st.ord][st.shipP]+e.cost;
          pque.push( State( dp[e.to][nord][st.shipP], e.to, nord, st.shipP ) );
        }
      }
    }

    short ans = INF;
    rep( i, N )
      ans = std::min( ans, dp[z[R-1]][R-1][i] );

    printf( "%d\\n", ans );
  }

  return 0;
}*/

#include <algorithm>
#include <cstdio>
#define rep(i, a) for (int i = 0; i < (a); ++i)

constexpr int MAX_N = 200, MAX_R = 1000,
              INF = std::numeric_limits<int>::max() >> 2;

int N, M;
int sea[MAX_N][MAX_N], land[MAX_N][MAX_N];
int R;
int z[MAX_R];
int dp[MAX_R + 1][MAX_N];

int main() {
  while (scanf("%d%d", &N, &M), N | M) {
    std::fill((int *)sea, (int *)(sea + N), INF);
    std::fill((int *)land, (int *)(land + N), INF);

    rep(i, N) sea[i][i] = land[i][i] = 0;

    rep(i, M) {
      int x, y, t;
      char sl;
      scanf("%d%d%d %c", &x, &y, &t, &sl);
      --x;
      --y;

      if (sl == 'S') {
        sea[x][y] = std::min(sea[x][y], t);
        sea[y][x] = std::min(sea[y][x], t);
      } else {
        land[x][y] = std::min(land[x][y], t);
        land[y][x] = std::min(land[y][x], t);
      }
    }

    scanf("%d", &R);

    rep(i, R) scanf("%d", z + i), --z[i];

    rep(k, N) rep(i, N) rep(j, N) {
      sea[i][j] = std::min(sea[i][j], sea[i][k] + sea[k][j]);
      land[i][j] = std::min(land[i][j], land[i][k] + land[k][j]);
    }

    std::fill((int *)dp, (int *)(dp + R), INF);
    dp[0][z[0]] = 0;

    rep(i, R - 1) rep(j, N) {
      dp[i + 1][j] = std::min(dp[i + 1][j], dp[i][j] + land[z[i + 1]][z[i]]);

      rep(k, N) dp[i + 1][k] =
          std::min(dp[i + 1][k],
                   dp[i][j] + land[z[i]][j] + sea[j][k] + land[z[i + 1]][k]);
    }

    printf("%d\\n", *std::min_element(dp[R - 1], dp[R - 1] + N));
  }

  return 0;
}


Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <limits>
#include <queue>
#include <utility>
#include <vector>
#define rep(i, a) for (int i = 0; i < (a); ++i)

constexpr int MAX_N = 200, MAX_R = 1000,
              INF = std::numeric_limits<int>::max() >> 2;

struct edge {
  int to, cost;
  bool ship;

  edge(int to, int cost, bool ship) : to(to), cost(cost), ship(ship) {}
};

struct State {
  int dist, v, ord, shipP;

  State(int dist, int v, int ord, int shipP)
      : dist(dist), v(v), ord(ord), shipP(shipP) {}

  bool operator<(const State &s) const { return this->dist > s.dist; }
};

int N, M;
std::vector<edge> G[MAX_N];
int R;
int z[MAX_R];
int dp[MAX_N][MAX_R][MAX_N];

int main() {
  while (scanf("%d%d", &N, &M), N | M) {
    rep(i, N) G[i].clear();

    rep(i, M) {
      int x, y, t;
      char sl;
      scanf("%d%d%d %c", &x, &y, &t, &sl);
      --x;
      --y;
      // putchar(sl);
      G[x].push_back(edge(y, t, sl == 'S'));
      G[y].push_back(edge(x, t, sl == 'S'));
    }

    scanf("%d", &R);
    rep(i, R) scanf("%d", z + i), --z[i];

    std::priority_queue<State> pque;
    pque.push(State(0, z[0], 0, 0));
    std::fill((int *)dp, (int *)(dp + N), INF);
    dp[z[0]][0][0] = 0;

    while (!pque.empty()) {
      State st = pque.top();
      pque.pop();

      if (st.dist > dp[st.v][st.ord][st.shipP] || st.ord == R - 1)
        continue;

      // printf( "[%d %d %d %d]\\n", st.dist, st.v, st.ord, st.shipP );

      for (auto e : G[st.v]) {
        int nord = e.to == z[st.ord + 1] ? st.ord + 1 : st.ord;

        if (st.shipP == st.v && e.ship &&
            dp[e.to][nord][e.to] > dp[st.v][st.ord][st.shipP] + e.cost) {
          dp[e.to][nord][e.to] = dp[st.v][st.ord][st.shipP] + e.cost;
          pque.push(State(dp[e.to][nord][e.to], e.to, nord, e.to));
        }

        if (!e.ship &&
            dp[e.to][nord][st.shipP] > dp[st.v][st.ord][st.shipP] + e.cost) {
          dp[e.to][nord][st.shipP] = dp[st.v][st.ord][st.shipP] + e.cost;
          pque.push(State(dp[e.to][nord][st.shipP], e.to, nord, st.shipP));
        }
      }
    }

    int ans = INF;
    rep(i, N) ans = std::min(ans, dp[z[R - 1]][R - 1][i]);

    printf("%d\\n", ans);
  }

  return 0;
}