Problem p01239 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <complex>
#include <iostream>
#include <vector>
using namespace std;

const double INF = 1e30;
typedef complex<double> P;
double dp[14][2][1 << 14];

int main() {
  int caseNum = 0;
  int N;
  while (cin >> N, N) {
    vector<P> points(2 * N);

    double sum = 0;
    for (int i = 0; i < N; i++) {
      double a, b, x, y;
      cin >> a >> b >> x >> y;
      points[2 * i + 0] = P(a, b);
      points[2 * i + 1] = P(x, y);

      sum += abs(points[2 * i] - points[2 * i + 1]);
    }

    for (int i = 0; i < (1 << N); i++)
      for (int j = 0; j < 14; j++)
        for (int k = 0; k < 2; k++)
          dp[j][k][i] = INF;

    for (int i = 0; i < N; i++)
      for (int j = 0; j < 2; j++)
        dp[i][j][1 << i] = 0;

    for (int i = 0; i < (1 << N); i++)
      for (int j = 0; j < N; j++) {
        if (!(i >> j & 1))
          continue;
        for (int a = 0; a < 2; a++)
          for (int k = 0; k < N; k++) {
            if (i >> k & 1)
              continue;
            for (int b = 0; b < 2; b++) {

              dp[k][b][i | (1 << k)] =
                  min(dp[k][b][i | (1 << k)],
                      dp[j][a][i] +
                          abs(points[2 * j + (a + 1) % 2] - points[2 * k + b]));
            }
          }
      }

    double res = INF;
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < N; j++)
        res = min(res, dp[j][i][(1 << N) - 1]);

    cout.setf(ios::fixed);
    cout.precision(10);
    cout << "Case " << ++caseNum << ": " << res + sum << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <complex>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const double INF = 1e30;
typedef complex<double> P;
bool vis[14][2][1 << 14];

class State {
public:
  int p, l, used;
  double c;
  State(int p, int l, int used, double c) : p(p), l(l), used(used), c(c) {}

  bool operator<(const State &s) const { return c > s.c; }
};

double solve(vector<P> &points) {
  int N = points.size() / 2;

  memset(vis, 0, sizeof(vis));

  priority_queue<State> q;
  for (int i = 0; i < N; i++)
    for (int j = 0; j < 2; j++)
      q.push(State(i, j, (1 << i), 0));

  while (!q.empty()) {
    State s = q.top();
    q.pop();
    if (s.used == (1 << N) - 1)
      return s.c;

    if (vis[s.p][s.l][s.used])
      continue;
    vis[s.p][s.l][s.used] = 1;

    for (int i = 0; i < N; i++) {
      if (s.used >> i & 1)
        continue;
      for (int j = 0; j < 2; j++) {
        if (vis[i][j][s.used | (1 << i)])
          continue;

        double cst =
            s.c + abs(points[2 * s.p + (s.l + 1) % 2] - points[2 * i + j]);
        q.push(State(i, j, s.used | (1 << i), cst));
      }
    }
  }

  return -1;
}

int main() {
  int caseNum = 0;
  int N;
  while (cin >> N, N) {
    vector<P> points(2 * N);

    double sum = 0;
    for (int i = 0; i < N; i++) {
      double a, b, x, y;
      cin >> a >> b >> x >> y;
      points[2 * i + 0] = P(a, b);
      points[2 * i + 1] = P(x, y);

      sum += abs(points[2 * i] - points[2 * i + 1]);
    }

    double res = solve(points) + sum;

    cout.setf(ios::fixed);
    cout.precision(10);
    cout << "Case " << ++caseNum << ": " << res << endl;
  }
}