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

#include <cassert>
#include <cstdio>
#include <iostream>
#include <list>
#include <set>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

#define f first
#define s second
#define mp make_pair

using namespace std;

struct Sectors {
  int start;
  int end;
  int id;
  Sectors() : start(0), end(1000000010), id(-1) {}
  Sectors(int s, int e, int i) : start(s), end(e), id(i) {}

  int size() { return end - start + 1; }
  bool isEmpty() { return id == -1; }
  bool isIn(int sec) { return start <= sec && sec <= end; }
};

int main() {
  int n;
  while (scanf("%d", &n), n) {
    list<Sectors> ss;
    int emp = 0;

    ss.push_back(Sectors());

    REP(cc, n) {
      char buff[2];
      scanf("%s", buff);
      if (buff[0] == 'W') {
        int l, s;
        scanf("%d%d", &l, &s);

        if (emp == 0) {
          list<Sectors>::iterator it = ss.end();
          --it;
          int start = it->start;
          int end = start + s - 1;
          it->start = end + 1;
          it = ss.insert(it, Sectors(start, end, l));
        } else {
          list<Sectors>::iterator it = ss.begin();
          while (s > 0) {
            if (it->isEmpty()) {
              int sz = it->size();
              if (sz > s) {
                int start = it->start;
                int end = start + s - 1;
                it->start = end + 1;
                it = ss.insert(it, Sectors(start, end, l));
                break;
              } else {
                s -= sz;
                it->id = l;
                emp--;
              }
            }

            assert(it != ss.end());
            ++it;
          }
        }
      } else if (buff[0] == 'D') {
        int l;
        scanf("%d", &l);
        FOR(it, ss) {
          if (it->id == l) {
            it->id = -1;
            emp++;
          }
        }
      } else {
        int sec;
        scanf("%d", &sec);

        FOR(it, ss) {
          if (it->isIn(sec)) {
            printf("%d\\n", it->id);
            break;
          }
        }
      }

      // FOR(it, ss)printf("[%d,%d]:%d ", it->start, it->end, it->id);puts("");
    }
    puts("");
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <queue>
#include <set>
#define REP(i, n) for (int i = 0; i < (int)(n); i++)

int getInt() {
  int ret = 0, c;
  c = getchar();
  while (!isdigit(c))
    c = getchar();
  while (isdigit(c)) {
    ret *= 10;
    ret += c - '0';
    c = getchar();
  }
  return ret;
}

using namespace std;

int inf = 1e8;

int minimum_steiner_tree(const vector<int> &T, const vector<vector<int>> &g) {
  const int n = g.size();
  const int numT = T.size();
  if (numT <= 1)
    return 0;

  vector<vector<int>> d(g); // all-pair shortest
  for (int k = 0; k < n; ++k)
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j)
        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);

  int OPT[(1 << numT)][n];
  for (int S = 0; S < (1 << numT); ++S)
    for (int x = 0; x < n; ++x)
      OPT[S][x] = inf;

  for (int p = 0; p < numT; ++p) // trivial case
    for (int q = 0; q < n; ++q)
      OPT[1 << p][q] = d[T[p]][q];

  for (int S = 1; S < (1 << numT); ++S) { // DP step
    if (!(S & (S - 1)))
      continue;
    for (int p = 0; p < n; ++p)
      for (int E = 0; E < S; ++E)
        if ((E | S) == S)
          OPT[S][p] = min(OPT[S][p], OPT[E][p] + OPT[S - E][p]);
    for (int p = 0; p < n; ++p)
      for (int q = 0; q < n; ++q)
        OPT[S][p] = min(OPT[S][p], OPT[S][q] + d[p][q]);
  }
  int ans = inf;
  for (int S = 0; S < (1 << numT); ++S)
    for (int q = 0; q < n; ++q)
      ans = min(ans, OPT[S][q] + OPT[((1 << numT) - 1) - S][q]);

  return ans;
}

int main() {
  while (true) {
    vector<int> v;
    int h = getInt();
    int w = getInt();

    if (h + w == 0)
      break;

    REP(i, h) REP(j, w) {
      if (getInt() == 1) {
        v.push_back(i * w + j);
      }
    }

    vector<vector<int>> g(h * w, vector<int>(h * w, inf));

    REP(i, h) REP(j, w) {
      g[i * w + j][i * w + j] = 0;
      if (i != h - 1) {
        g[i * w + j][(i + 1) * w + j] = g[(i + 1) * w + j][i * w + j] = 1;
      }
      if (j != w - 1) {
        g[i * w + j][i * w + j + 1] = g[i * w + j + 1][i * w + j] = 1;
      }
    }

    int ans = w * h - (minimum_steiner_tree(v, g) + 1);

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