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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define INF 1000000007
#define fi first
#define se second
#define show(x) cout << #x << " = " << x << "\\n"

using namespace std;

typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef pair<PP, int> PPI;

struct edge {
  int to, cost, id;
};

template <typename T> class LIS2D {
private:
  using ptt = pair<T, T>;
  set<ptt> st;

public:
  bool insert(pair<T, T> val) {
    bool in = false;
    auto it = st.lower_bound(val);
    if (it != st.end()) {
      if (*it == val)
        return in;
      in = (it->second >= val.second);
    }
    if (in) {
      while (it != st.end() && it->second >= val.second) {
        it = st.erase(it);
      }
    } else {
      if (it != st.begin()) {
        it--;
        in = (it->second > val.second);
      } else {
        in = true;
      }
    }
    if (in)
      st.insert(val);
    return in;
  }
  void print() {
    for (auto &val : st) {
      cout << "{" << val.first << "," << val.second << "}"
           << " ";
    }
    cout << "\\n";
  }
};

int dd[21][20001];
vector<edge> G[101];

int n, m, s, c, g;

int Dijkstra() {
  LIS2D<int> dp[101][21];
  priority_queue<PPI, vector<PPI>, greater<PPI>> que;
  que.push(PPI(PP(P(0, s), P(0, 0)), 0));
  rep(i, c) { dp[s][i].insert(P(-INF, 0)); }
  while (!que.empty()) {
    auto pp = que.top();
    auto p = pp.first;
    que.pop();
    int cost = (p.fi).fi, st = (p.fi).se, com = (p.se).fi, dist = (p.se).se,
        cnt = pp.second;
    if (cnt >= n)
      continue;
    if (st == g)
      return cost;
    for (auto &e : G[st]) {
      if (e.id == com) {
        int new_cost = cost - dd[com][dist] + dd[com][dist + e.cost];
        if (dp[e.to][com].insert(P(-dist - e.cost, new_cost))) {
          que.push(PPI(PP(P(new_cost, e.to), P(com, dist + e.cost)), cnt + 1));
        }
      } else {
        if (dp[e.to][e.id].insert(P(-e.cost, cost + dd[e.id][e.cost]))) {
          que.push(
              PPI(PP(P(cost + dd[e.id][e.cost], e.to), P(e.id, e.cost)), 1));
        }
      }
    }
  }
}

class UF {
private:
  int sz;
  vector<int> par, nrank;

public:
  UF() {}
  UF(int node_size) {
    sz = node_size;
    par.resize(sz), nrank.resize(sz, 0);
    rep(i, sz) par[i] = i;
  }
  int find(int x) {
    if (par[x] == x) {
      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;
    if (nrank[x] < nrank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (nrank[x] == nrank[y])
        nrank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

int main() {
  while (1) {
    cin >> n >> m >> c >> s >> g;
    if (n == 0) {
      break;
    }
    s--, g--;
    rep(i, n) { G[i].clear(); }
    UF uf(n);
    rep(i, m) {
      int x, y, d, cs;
      cin >> x >> y >> d >> cs;
      G[x - 1].push_back((edge){y - 1, d, cs - 1});
      G[y - 1].push_back((edge){x - 1, d, cs - 1});
      uf.unite(x - 1, y - 1);
    }
    vector<int> p(c);
    rep(i, c) { cin >> p[i]; }
    rep(i, c) {
      vector<int> q(p[i]), r(p[i]);
      q[0] = 0;
      rep(j, p[i] - 1) { cin >> q[j + 1]; }
      rep(j, p[i]) { cin >> r[j]; }
      rep(j, p[i] - 1) {
        rep(k, q[j + 1] - q[j]) {
          dd[i][q[j] + k + 1] = dd[i][q[j] + k] + r[j];
        }
      }
      for (int j = q[p[i] - 1] + 1; j <= 20000; j++) {
        dd[i][j] = dd[i][j - 1] + r[p[i] - 1];
      }
    }
    if (uf.same(s, g)) {
      cout << Dijkstra() << "\\n";
    } else {
      cout << "-1\\n";
    }
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define INF 1000000007
#define fi first
#define se second
#define show(x) cout << #x << " = " << x << "\\n"

using namespace std;

typedef pair<int, int> P;
typedef pair<P, P> PP;
typedef pair<PP, int> PPI;

struct edge {
  int to, cost, id;
};

template <typename T> class LIS2D {
private:
  using ptt = pair<T, T>;
  set<ptt> st;

public:
  bool insert(pair<T, T> val) {
    bool in = false;
    auto it = st.lower_bound(val);
    if (it != st.end()) {
      if (*it == val)
        return in;
      in = (it->second >= val.second);
    }
    if (in) {
      while (it != st.end() && it->second >= val.second) {
        it = st.erase(it);
      }
    } else {
      if (it != st.begin()) {
        it--;
        in = (it->second > val.second);
      } else {
        in = true;
      }
    }
    if (in)
      st.insert(val);
    return in;
  }
  void print() {
    for (auto &val : st) {
      cout << "{" << val.first << "," << val.second << "}"
           << " ";
    }
    cout << "\\n";
  }
};

int dd[21][20001];
vector<edge> G[101];

int n, m, s, c, g;

int Dijkstra() {
  LIS2D<int> dp[101][21];
  priority_queue<PPI, vector<PPI>, greater<PPI>> que;
  que.push(PPI(PP(P(0, s), P(0, 0)), 0));
  rep(i, c) { dp[s][i].insert(P(-INF, 0)); }
  while (!que.empty()) {
    auto pp = que.top();
    auto p = pp.first;
    que.pop();
    int cost = (p.fi).fi, st = (p.fi).se, com = (p.se).fi, dist = (p.se).se,
        cnt = pp.second;
    if (cnt >= n)
      continue;
    if (st == g) {
      return cost;
    }
    for (auto &e : G[st]) {
      if (e.id == com) {
        int new_cost = cost - dd[com][dist] + dd[com][dist + e.cost];
        if (dp[e.to][com].insert(P(-dist - e.cost, new_cost))) {
          que.push(PPI(PP(P(new_cost, e.to), P(com, dist + e.cost)), cnt + 1));
        }
      } else {
        if (dp[e.to][e.id].insert(P(-e.cost, cost + dd[e.id][e.cost]))) {
          que.push(
              PPI(PP(P(cost + dd[e.id][e.cost], e.to), P(e.id, e.cost)), 1));
        }
      }
    }
  }
  return -1;
}

int main() {
  while (1) {
    cin >> n >> m >> c >> s >> g;
    if (n == 0) {
      break;
    }
    s--, g--;
    rep(i, n) { G[i].clear(); }
    rep(i, m) {
      int x, y, d, cs;
      cin >> x >> y >> d >> cs;
      G[x - 1].push_back((edge){y - 1, d, cs - 1});
      G[y - 1].push_back((edge){x - 1, d, cs - 1});
    }
    vector<int> p(c);
    rep(i, c) { cin >> p[i]; }
    rep(i, c) {
      vector<int> q(p[i]), r(p[i]);
      q[0] = 0;
      rep(j, p[i] - 1) { cin >> q[j + 1]; }
      rep(j, p[i]) { cin >> r[j]; }
      rep(j, p[i] - 1) {
        rep(k, q[j + 1] - q[j]) {
          dd[i][q[j] + k + 1] = dd[i][q[j] + k] + r[j];
        }
      }
      for (int j = q[p[i] - 1] + 1; j <= 20000; j++) {
        dd[i][j] = dd[i][j - 1] + r[p[i] - 1];
      }
    }
    cout << Dijkstra() << "\\n";
  }
}