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

#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

int s[210][210];  // 水路
int l[210][210];  //?路
int d[1010][210]; // dp
int b[1010];      // 目?路?

const int INF = 0x3f3f3f3f;

void Floyd(int n) {
  for (int k = 1; k <= n; ++k) {
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j <= n; ++j) {
        s[i][j] = min(s[i][j], s[i][k] + s[k][j]);
        l[i][j] = min(l[i][j], l[i][k] + l[k][j]);
      }
    }
  }
}

int main() {
  int n, m, r;
  int u, v, c;
  char tp[2];

  while (scanf("%d%d", &n, &m) != EOF && n) {
    memset(s, INF, sizeof(s));
    memset(l, INF, sizeof(l));
    memset(d, INF, sizeof(d));

    while (m--) {
      scanf("%d%d%d%s", &u, &v, &c, tp);
      if (tp[0] == 'L') {
        l[u][v] = min(l[u][v], c);
        l[v][u] = min(l[v][u], c);
      } else {
        s[u][v] = min(s[u][v], c);
        s[v][u] = min(s[v][u], c);
      }
    }

    for (int i = 1; i <= n; ++i) {
      l[i][i] = 0;
      s[i][i] = 0;
    }

    scanf("%d", &r);

    for (int i = 1; i <= r; ++i) {
      scanf("%d", &b[i]);
    }

    Floyd(n);

    for (int i = 1; i <= n; ++i) {
      d[1][i] = min(d[1][i], s[b[1]][i] + l[i][b[1]]);
    }

    for (int i = 1; i <= r; ++i) {
      for (int j = 1; j <= n; ++j) {
        // if (l[j][b[i]] >= INF) continue;
        for (int k = 1; k <= n; ++k) {
          // if (d[i - 1][k] >= INF) continue;
          if (j == k) {
            if (l[b[i - 1]][b[i]] < INF) {
              d[i][j] = min(d[i][j], d[i - 1][k] + l[b[i - 1]][b[i]]);
            }
          } else {
            // 三个INF可能上溢
            if (l[b[i - 1]][k] < INF && s[k][j] < INF && l[j][b[i]] < INF) {
              d[i][j] = min(d[i][j], d[i - 1][k] + l[b[i - 1]][k] + s[k][j] +
                                         l[j][b[i]]);
            }
          }
        }
      }
    }

    int ans = INF;
    for (int j = 1; j <= n; ++j) {
      ans = min(ans, d[r][j]);
    }
    printf("%d\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <queue>
#include <stdio.h>
#include <string.h>
#define oo 0x3f3f3f3f
using namespace std;
struct ad {
  int to, next, v, water;
} edge[33000];
struct node {
  int people_pos, ship_pos, cnt, water;
};
int head[3300], edge_num, vis[300][1100][2], k, End[1100], dist[300][1100][2],
    n;
void Add(int x, int y, int z, int op) {
  edge[edge_num].to = y;
  edge[edge_num].v = z;
  edge[edge_num].next = head[x];
  edge[edge_num].water = op;
  head[x] = edge_num++;
}
int spfa() {
  queue<node> Q;
  node now, next;
  now.people_pos = End[1];
  now.ship_pos = End[1];
  now.cnt = 1;
  now.water = 0;
  Q.push(now);

  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= k; j++) {
      dist[i][j][0] = dist[i][j][1] = oo;
      vis[i][j][0] = vis[i][j][1] = 0;
    }

  dist[End[1]][1][0] = dist[End[1]][1][1] = 0;
  vis[End[1]][1][0] = 1;
  while (!Q.empty()) {
    now = Q.front();
    Q.pop();

    for (int i = head[now.people_pos]; ~i; i = edge[i].next) {
      int v = edge[i].to;
      int new_cnt = now.cnt;
      if (v == End[now.cnt + 1])
        new_cnt++;
      if (!edge[i].water) {
        if (dist[v][new_cnt][edge[i].water] >
            dist[now.people_pos][now.cnt][now.water] + edge[i].v) {
          dist[v][new_cnt][edge[i].water] =
              dist[now.people_pos][now.cnt][now.water] + edge[i].v;
          if (!vis[v][new_cnt][edge[i].water]) {
            vis[v][new_cnt][edge[i].water] = 1;
            next.people_pos = v;
            next.water = 0;
            next.ship_pos = now.ship_pos;
            next.cnt = new_cnt;
            Q.push(next);
          }
        }
      } else if (now.ship_pos == now.people_pos) {
        if (dist[v][new_cnt][edge[i].water] >
            dist[now.people_pos][now.cnt][now.water] + edge[i].v) {
          dist[v][new_cnt][edge[i].water] =
              dist[now.people_pos][now.cnt][now.water] + edge[i].v;
          if (!vis[v][new_cnt][edge[i].water]) {
            vis[v][new_cnt][edge[i].water] = 1;
            next.people_pos = v;
            next.ship_pos = v;
            next.cnt = new_cnt;
            next.water = 1;
            Q.push(next);
          }
        }
      }
    }
    vis[now.people_pos][now.cnt][now.water] = 0;
  }

  return min(dist[End[k]][k][0], dist[End[k]][k][1]);
}
int main() {
  int m;
  while (scanf("%d %d", &n, &m), n + m) {
    memset(head, -1, sizeof(head));
    memset(End, 0, sizeof(End));
    edge_num = 0;
    int u, v, w;
    char way[5];
    for (int i = 1; i <= m; i++) {
      scanf("%d %d %d %s", &u, &v, &w, way);
      Add(u, v, w, way[0] == 'S');
      Add(v, u, w, way[0] == 'S');
    }

    scanf("%d", &k);

    for (int i = 1; i <= k; i++)
      scanf("%d", &End[i]);

    printf("%d\\n", spfa());
  }
  return 0;
}