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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define FOREQ(i, k, n) for (int i = (k); i <= (int)(n); ++i)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define SZ(v) (int)((v).size())
#define MEMSET(v, h) memset((v), (h), sizeof(v))

typedef vector<int> Array;
typedef vector<Array> Matrix;

int n, m;
Matrix mainG[2];
map<int, map<int, Matrix>> hMatrix[2];
int height[100];
int fee[100];
int order[100];
map<int, int> heightCnt;
map<int, int> mapto;
map<int, map<int, int>> mapfrom;

int dp[60][60];

void PushHeight(int index, int h) {
  mapto[index] = heightCnt[h];
  mapfrom[h][heightCnt[h]] = index;
  heightCnt[h]++;
}

void PushEdge(int from, int to, int c) {
  if (height[from] < height[to]) {
    mainG[0][from][to] = c;
  }
  if (height[from] > height[to]) {
    mainG[1][to][from] = c;
  }
  if (height[from] == height[to]) {
    int h = height[from];
    int l = mapto[from];
    int r = mapto[to];
    REP(i, 1 << heightCnt[h]) {
      if (!((i >> l) & 1)) {
        continue;
      }
      if (!((i >> r) & 1)) {
        continue;
      }
      hMatrix[0][h][i][l][r] = c;
      hMatrix[1][h][i][r][l] = c;
    }
  }
}

void CalcMatrix(Matrix &m) {
  int n = m.size();
  REP(k, n) REP(i, n) REP(j, n) { m[i][j] = min(m[i][j], m[i][k] + m[k][j]); }
}

int CalcFee(int h, int use) {
  int ret = 0;
  REP(i, heightCnt[h]) {
    if ((use >> i) & 1) {
      ret += fee[mapfrom[h][i]];
    }
  }
  return ret;
}

int main() {
  while (scanf("%d %d", &n, &m), n | m) {
    MEMSET(fee, 0);
    mainG[0] = Matrix(n, Array(n, 1 << 27));
    mainG[1] = Matrix(n, Array(n, 1 << 27));
    hMatrix[0].clear();
    hMatrix[1].clear();
    heightCnt.clear();
    mapto.clear();
    mapfrom.clear();
    FOR(i, 1, n - 1) {
      scanf("%d %d", &fee[i], &height[i]);
      PushHeight(i, height[i]);
    }
    height[0] = -1;
    height[n - 1] = 10000;
    PushHeight(0, -1);
    PushHeight(n - 1, 10000);
    {
      int cnt = 0;
      FORIT(it1, mapfrom) {
        FORIT(it2, it1->second) { order[cnt++] = it2->second; }
      }
    }
    FORIT(it, heightCnt) {
      int h = it->first;
      REP(i, 1 << it->second) {
        int c = it->second;
        hMatrix[0][h][i] = Matrix(c, Array(c, 1 << 27));
        hMatrix[1][h][i] = Matrix(c, Array(c, 1 << 27));
        REP(j, it->second) {
          if (!((i >> j) & 1)) {
            continue;
          }
          hMatrix[0][h][i][j][j] = 0;
          hMatrix[1][h][i][j][j] = 0;
        }
      }
    }
    REP(i, m) {
      int from, to, c;
      scanf("%d %d %d", &from, &to, &c);
      from--;
      to--;
      PushEdge(from, to, c);
    }
    REP(iter, 2) {
      FORIT(it1, hMatrix[iter]) {
        FORIT(it2, it1->second) {
          Matrix &m = it2->second;
          CalcMatrix(m);
        }
      }
    }

    MEMSET(dp, 0x0f);
    dp[0][0] = 0;
    // process

    REP(i, n) REP(j, n) {
      int l = order[i];
      int r = order[j];
      if (height[l] < height[r]) {
        int h = height[l];
        FOR(use, 1, 1 << heightCnt[h]) {
          if (!((use >> mapto[l]) & 1)) {
            continue;
          }
          const Matrix &mat0 = hMatrix[0][h][use];
          int f = CalcFee(h, use) - fee[l];
          // cout << l << " " << r << " " << f << endl;
          assert(f >= 0);
          REP(k, heightCnt[h]) {
            int ncost = mat0[mapto[l]][k] + f + dp[l][r];
            int nl = mapfrom[h][k];
            dp[nl][r] = min(dp[nl][r], ncost);

            REP(to, n) {
              int nc = dp[nl][r] + fee[to] + mainG[0][nl][to];
              if (to == r) {
                nc -= fee[to];
              }
              dp[to][r] = min(dp[to][r], nc);
            }
          }
        }
      } else if (height[l] > height[r]) {
        int h = height[r];
        FOR(use, 1, 1 << heightCnt[h]) {
          if (!((use >> mapto[r]) & 1)) {
            continue;
          }
          const Matrix &mat1 = hMatrix[1][h][use];
          int f = CalcFee(h, use) - fee[r];
          assert(f >= 0);
          REP(k, heightCnt[h]) {
            int ncost = mat1[mapto[r]][k] + f + dp[l][r];
            int nr = mapfrom[h][k];
            dp[l][nr] = min(dp[l][nr], ncost);
            REP(to, n) {
              int nc = dp[l][nr] + fee[to] + mainG[1][nr][to];
              if (to == l) {
                nc -= fee[to];
              }
              dp[l][to] = min(dp[l][to], nc);
            }
          }
        }
      } else {
        int h = height[l];
        FOR(use, 1, 1 << heightCnt[h]) {
          if (!((use >> mapto[l]) & 1)) {
            continue;
          }
          if (!((use >> mapto[r]) & 1)) {
            continue;
          }
          const Matrix &mat0 = hMatrix[0][h][use];
          const Matrix &mat1 = hMatrix[1][h][use];
          int f = CalcFee(h, use) - fee[l] - fee[r];
          if (l == r) {
            f += fee[l];
          }
          assert(f >= 0);
          REP(s, heightCnt[h]) {
            int nr = mapfrom[h][s];
            REP(k, heightCnt[h]) {
              int ncost = mat0[mapto[l]][k] + mat1[mapto[r]][s] + f + dp[l][r];
              int nl = mapfrom[h][k];
              dp[nl][nr] = min(dp[nl][nr], ncost);
            }
            REP(to, n) {
              int nc = dp[l][nr] + fee[to] + mainG[1][nr][to];
              if (to == l) {
                nc -= fee[to];
              }
              dp[l][to] = min(dp[l][to], nc);
            }
          }
        }
      }
    }
    if (dp[n - 1][n - 1] > (1 << 24)) {
      puts("-1");
    } else {
      printf("%d\\n", dp[n - 1][n - 1]);
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define FOREQ(i, k, n) for (int i = (k); i <= (int)(n); ++i)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define SZ(v) (int)((v).size())
#define MEMSET(v, h) memset((v), (h), sizeof(v))

typedef vector<int> Array;
typedef vector<Array> Matrix;

int n, m;
Matrix mainG[2];
map<int, map<int, Matrix>> hMatrix[2];
int height[100];
int fee[100];
int order[100];
map<int, int> heightCnt;
map<int, int> mapto;
map<int, map<int, int>> mapfrom;

int dp[60][60];

void PushHeight(int index, int h) {
  mapto[index] = heightCnt[h];
  mapfrom[h][heightCnt[h]] = index;
  heightCnt[h]++;
}

void PushEdge(int from, int to, int c) {
  if (height[from] < height[to]) {
    mainG[0][from][to] = c;
  }
  if (height[from] > height[to]) {
    mainG[1][to][from] = c;
  }
  if (height[from] == height[to]) {
    int h = height[from];
    int l = mapto[from];
    int r = mapto[to];
    REP(i, 1 << heightCnt[h]) {
      if (!((i >> l) & 1)) {
        continue;
      }
      if (!((i >> r) & 1)) {
        continue;
      }
      hMatrix[0][h][i][l][r] = c;
      hMatrix[1][h][i][r][l] = c;
    }
  }
}

void CalcMatrix(Matrix &m) {
  int n = m.size();
  REP(k, n) REP(i, n) REP(j, n) { m[i][j] = min(m[i][j], m[i][k] + m[k][j]); }
}

int CalcFee(int h, int use) {
  int ret = 0;
  REP(i, heightCnt[h]) {
    if ((use >> i) & 1) {
      ret += fee[mapfrom[h][i]];
    }
  }
  return ret;
}

int main() {
  while (scanf("%d %d", &n, &m), n | m) {
    MEMSET(fee, 0);
    mainG[0] = Matrix(n, Array(n, 1 << 27));
    mainG[1] = Matrix(n, Array(n, 1 << 27));
    hMatrix[0].clear();
    hMatrix[1].clear();
    heightCnt.clear();
    mapto.clear();
    mapfrom.clear();
    FOR(i, 1, n - 1) {
      scanf("%d %d", &fee[i], &height[i]);
      PushHeight(i, height[i]);
    }
    height[0] = -1;
    height[n - 1] = 10000;
    PushHeight(0, -1);
    PushHeight(n - 1, 10000);
    {
      int cnt = 0;
      FORIT(it1, mapfrom) {
        FORIT(it2, it1->second) { order[cnt++] = it2->second; }
      }
    }
    FORIT(it, heightCnt) {
      int h = it->first;
      REP(i, 1 << it->second) {
        int c = it->second;
        hMatrix[0][h][i] = Matrix(c, Array(c, 1 << 27));
        hMatrix[1][h][i] = Matrix(c, Array(c, 1 << 27));
        REP(j, it->second) {
          if (!((i >> j) & 1)) {
            continue;
          }
          hMatrix[0][h][i][j][j] = 0;
          hMatrix[1][h][i][j][j] = 0;
        }
      }
    }
    REP(i, m) {
      int from, to, c;
      scanf("%d %d %d", &from, &to, &c);
      from--;
      to--;
      PushEdge(from, to, c);
    }
    REP(iter, 2) {
      FORIT(it1, hMatrix[iter]) {
        FORIT(it2, it1->second) {
          Matrix &m = it2->second;
          CalcMatrix(m);
        }
      }
    }

    MEMSET(dp, 0x0f);
    dp[0][0] = 0;
    // process

    REP(i, n) REP(j, n) {
      int l = order[i];
      int r = order[j];
      if (height[l] < height[r]) {
        int h = height[l];
        FOR(use, 1, 1 << heightCnt[h]) {
          if (!((use >> mapto[l]) & 1)) {
            continue;
          }
          int f = CalcFee(h, use) - fee[l];
          // cout << l << " " << r << " " << f << endl;
          assert(f >= 0);
          REP(k, heightCnt[h]) {
            int ncost = hMatrix[0][h][use][mapto[l]][k] + f + dp[l][r];
            int nl = mapfrom[h][k];
            dp[nl][r] = min(dp[nl][r], ncost);

            REP(to, n) {
              int nc = dp[nl][r] + fee[to] + mainG[0][nl][to];
              if (to == r) {
                nc -= fee[to];
              }
              dp[to][r] = min(dp[to][r], nc);
            }
          }
        }
      } else if (height[l] > height[r]) {
        int h = height[r];
        FOR(use, 1, 1 << heightCnt[h]) {
          if (!((use >> mapto[r]) & 1)) {
            continue;
          }
          int f = CalcFee(h, use) - fee[r];
          assert(f >= 0);
          REP(k, heightCnt[h]) {
            int ncost = hMatrix[1][h][use][mapto[r]][k] + f + dp[l][r];
            int nr = mapfrom[h][k];
            dp[l][nr] = min(dp[l][nr], ncost);
            REP(to, n) {
              int nc = dp[l][nr] + fee[to] + mainG[1][nr][to];
              if (to == l) {
                nc -= fee[to];
              }
              dp[l][to] = min(dp[l][to], nc);
            }
          }
        }
      } else {
        int h = height[l];
        FOR(use, 1, 1 << heightCnt[h]) {
          if (!((use >> mapto[l]) & 1)) {
            continue;
          }
          if (!((use >> mapto[r]) & 1)) {
            continue;
          }
          int f = CalcFee(h, use) - fee[l] - fee[r];
          if (l == r) {
            f += fee[l];
          }
          assert(f >= 0);
          REP(k, heightCnt[h]) {
            REP(s, heightCnt[h]) {
              int ncost = hMatrix[0][h][use][mapto[l]][k] +
                          hMatrix[1][h][use][mapto[r]][s] + f + dp[l][r];
              int nl = mapfrom[h][k];
              int nr = mapfrom[h][s];
              dp[nl][nr] = min(dp[nl][nr], ncost);
              REP(to, n) {
                int nc = dp[l][nr] + fee[to] + mainG[1][nr][to];
                if (to == l) {
                  nc -= fee[to];
                }
                dp[l][to] = min(dp[l][to], nc);
              }
            }
          }
        }
      }
    }
    // REP(i, n) {
    //     REP(j, n) {
    //         cout << dp[i][j] << " ";
    //     }
    //     puts("");
    // }
    if (dp[n - 1][n - 1] > (1 << 24)) {
      puts("-1");
    } else {
      printf("%d\\n", dp[n - 1][n - 1]);
    }
  }
}