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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <queue>
#include <string>
#include <vector>

using namespace std;
typedef pair<int, int> P;
typedef long long ll;
int n, m, c, s, g;
int x, y, d, ct;
int p[21], q[21][61], r[21][61];
int fie[101][101][21];
int fie2[101][101];
int dp[101];

int dijk() {
  priority_queue<P, vector<P>, greater<P>> que;
  que.push(P(0, s));
  while (que.size()) {
    P q = que.top();
    que.pop();
    int cost = q.first, place = q.second;
    if (dp[place] < cost)
      continue;
    dp[place] = cost;
    if (place == g)
      return cost;
    for (int i = 1; i <= n; i++) {
      int ncost = cost + fie2[place][i];
      if (ncost < dp[i]) {
        dp[i] = ncost;
        que.push(P(ncost, i));
      }
    }
  }
  return -1;
}

int main(void) {
  while (1) {
    scanf("%d%d%d%d%d", &n, &m, &c, &s, &g);
    if (n + m + c + s + g == 0)
      break;
    for (int i = 0; i <= 20; i++) {
      q[i][0] = 0;
      for (int j = 1; j <= 60; j++)
        q[i][j] = 514514191;
      for (int j = 0; j <= 100; j++) {
        for (int k = 0; k <= 100; k++)
          fie[j][k][i] = 514514191;
        fie[j][j][i] = 0;
      }
    }
    for (int i = 0; i <= 100; i++) {
      dp[i] = 514514191;
      for (int j = 0; j <= 100; j++)
        fie2[i][j] = 514514191;
      fie2[i][i] = 0;
    }
    for (int i = 0; i < m; i++) {
      scanf("%d%d%d%d", &x, &y, &d, &ct);
      fie[x][y][ct] = min(fie[x][y][ct], d);
      fie[y][x][ct] = min(fie[y][x][ct], d);
    }
    for (int i = 1; i <= c; i++)
      scanf("%d", &p[i]);
    for (int i = 1; i <= c; i++) {
      for (int j = 1; j < p[i]; j++)
        scanf("%d", &q[i][j]);
      for (int j = 0; j < p[i]; j++)
        scanf("%d", &r[i][j]);
    }
    for (int l = 1; l <= c; l++) {
      for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
          for (int j = 1; j <= n; j++)
            fie[i][j][l] = min(fie[i][j][l], fie[i][k][l] + fie[k][j][l]);
        }
      }
    }
    for (int l = 1; l <= c; l++) {
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          int lx = 0, cost = 0;
          if (fie[i][j][l] == 514514191)
            continue;
          while (q[l][lx] < fie[i][j][l]) {
            if (q[l][lx + 1] < fie[i][j][l])
              cost += (q[l][lx + 1] - q[l][lx]) * r[l][lx];
            else
              cost += (fie[i][j][l] - q[l][lx]) * r[l][lx];
            lx++;
          }
          fie[i][j][l] = cost;
        }
      }
    }
    for (int l = 1; l <= c; l++) {
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++)
          fie2[i][j] = min(fie2[i][j], fie[i][j][l]);
      }
    }
    printf("%d\\n", dijk());
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>

using namespace std;
typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef pair<int, P> P2;
int n, m, c, s, g;
int x, y, d, ct;
vector<P2> train[101];
int p[21], q[21][61], r[21][61];
// 駅,前乗った鉄道会社
map<int, map<int, map<int, int>>> dp;
map<int, map<int, map<int, int>>> dp2;
int dijk() {
  priority_queue<PP, vector<PP>, greater<PP>> que;
  // コスト,今いる場所,来た鉄道の種類,今の鉄道で進んだ距離
  que.push(PP(P(0, s), P(0, 0)));
  while (que.size()) {
    PP qni = que.top();
    que.pop();
    int pcost = qni.first.first, pp = qni.first.second;
    int pc = qni.second.first, pd = qni.second.second;
    if (dp[pp][pc][pd] < pcost && dp2[pp][pc][pd] != 0)
      continue;
    dp[pp][pc][pd] = pcost;
    dp2[pp][pc][pd] = 1;
    // printf("kosin%d %d %d %d\\n",pp,pc,pd,pcost);
    if (pp == g)
      return pcost;
    for (int k = 0; k < train[pp].size(); k++) {
      int ppd = pd;
      P2 tr = train[pp][k];
      int np = tr.first, plusd = tr.second.first, nc = tr.second.second;
      int scost = pcost, nd;
      // printf("miti%d %d %d %d\\n",k,np,plusd,nc);
      if (nc != pc)
        nd = plusd, ppd = 0;
      else
        nd = plusd + ppd;
      if (p[nc] == 1)
        scost += plusd * r[nc][0];
      else {
        int lx = 0;
        for (int i = 0; i < p[nc]; i++)
          if (q[nc][i] <= ppd && ppd < q[nc][i + 1])
            lx = i;
        int sp = 0;
        while (sp < plusd) {
          if (lx == p[nc]) {
            scost += r[nc][lx] * (plusd - sp);
            sp = plusd;
          } else {
            int ssd = q[nc][lx + 1] - ppd;
            // printf("%d %d %d %d %d\\n",nc,lx,q[nc][lx],q[nc][lx+1],ppd);
            if (ssd <= 0)
              return -2;
            if (ssd + sp <= plusd)
              scost += r[nc][lx] * ssd;
            else
              scost += r[nc][lx] * (plusd - sp);
            lx++;
            ppd = q[nc][lx];
            sp += ssd;
          }
        }
      }
      nd = min(nd, 10000);
      if (dp[np][nc][nd] > scost || dp2[np][nc][nd] == 0) {
        dp[np][nc][nd] = scost;
        dp2[np][nc][nd] = 1;
        que.push(PP(P(scost, np), P(nc, nd)));
      }
    }
  }
  return -1;
}

int main(void) {
  while (1) {
    scanf("%d%d%d%d%d", &n, &m, &c, &s, &g);
    if (n + m + c + s + g == 0)
      break;
    dp2.clear();
    dp.clear();
    for (int i = 0; i <= 20; i++) {
      q[i][0] = 0;
      for (int j = 1; j <= 60; j++)
        q[i][j] = 114514;
    }
    for (int i = 0; i <= 100; i++)
      train[i].clear();
    for (int i = 0; i < m; i++) {
      scanf("%d%d%d%d", &x, &y, &d, &ct);
      train[x].push_back(P2(y, P(d, ct)));
      train[y].push_back(P2(x, P(d, ct)));
    }
    for (int i = 1; i <= c; i++)
      scanf("%d", &p[i]);
    for (int i = 1; i <= c; i++) {
      for (int j = 1; j <= p[i] - 1; j++)
        scanf("%d", &q[i][j]);
      for (int j = 0; j < p[i]; j++)
        scanf("%d", &r[i][j]);
    }
    printf("%d\\n", dijk());
  }
  return 0;
}