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

#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype

template <class T> int __builtin_popcount(T n) {
  return n ? 1 + __builtin_popcount(n & (n - 1)) : 0;
}
#endif

#define foreach(it, c)                                                         \\
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define popcount __builtin_popcount

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T &a, const T b) { a = max(a, b); }
template <class T> void min_swap(T &a, const T b) { a = min(a, b); }

const double EPS = 1e-10;
typedef long long ll;
typedef pair<int, int> pint;

deque<int> edge[24][4];
int n;
// int dp[24][1 << 23];
map<int, map<int, int>> dp;
int dfs(int p, int visit) {
  if (dp[p].count(visit))
    return dp[p][visit];
  else if (!visit) {
    bool f = false;
    rep(i, 4) foreach (e, edge[p][i]) f |= *e == n;
    return dp[p][visit] = f ? 1 : 0;
    // return f ? 1 : 0;
  }

  int res = 0;
  rep(i, 4) {
    foreach (e, edge[p][i]) {
      if (*e == n)
        continue;

      if (visit & (1 << *e)) {
        res += dfs(*e, visit ^ (1 << *e));
        break;
      }
    }
  }

  return dp[p][visit] = res;
  // return res;
}
int main() {
  int w, h;
  while (scanf("%d%d", &w, &h), w | h) {
    rep(i, 24) rep(j, 4) edge[i][j].clear();

    pint church;
    vector<pint> pos;
    rep(i, h) {
      rep(j, w) {
        int t;
        scanf("%d", &t);
        if (t == 1)
          pos.push_back(pint(j, i));
        else if (t == 2)
          church = pint(j, i);
      }
    }
    n = pos.size();
    pos.push_back(church);

    rep(i, pos.size()) {
      vector<pint> hor, ver;
      rep(j, pos.size()) {
        if (pos[i].first == pos[j].first)
          ver.push_back(pint(pos[j].second, j));
        else if (pos[i].second == pos[j].second)
          hor.push_back(pint(pos[j].first, j));
      }
      sort(all(hor));
      sort(all(ver));

      foreach (it, hor) {
        if (it->first < pos[i].first)
          edge[i][3].push_front(it->second);
        else if (pos[i].first < it->first)
          edge[i][1].push_back(it->second);
      }
      foreach (it, ver) {
        if (it->first < pos[i].second)
          edge[i][2].push_front(it->second);
        else if (pos[i].second < it->first)
          edge[i][0].push_back(it->second);
      }
    }

    // rep (i, n + 1)
    //{
    //	printf(">%d: (%d, %d)\\n", i, pos[i].first, pos[i].second);
    //	rep (j, 4)
    //	{
    //		printf("%d: ", j);
    //		foreach (t, edge[i][j])
    //			printf("(%d, %d) ", pos[*t].first, pos[*t].second);
    //		puts("");
    //	}
    // }

    // memset(dp, ~0, sizeof(dp));
    dp.clear();
    int all_visit = (1 << n) - 1;
    printf("%d\\n", dfs(n, all_visit));

    // int s = 0;
    // rep (i, n)
    //	if (~dp[i][0])
    //		s += dp[i][0];
    // printf("%d\\n", s);
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype

template <class T> int __builtin_popcount(T n) {
  return n ? 1 + __builtin_popcount(n & (n - 1)) : 0;
}
#endif

#define foreach(it, c)                                                         \\
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define popcount __builtin_popcount

#define rep(i, n) for (int i = 0; i < n; ++i)

template <class T> void max_swap(T &a, const T b) { a = max(a, b); }
template <class T> void min_swap(T &a, const T b) { a = min(a, b); }

const double EPS = 1e-10;
typedef long long ll;
typedef pair<int, int> pint;

deque<int> edge[24][4];
int n;
// int dp[24][1 << 23];
map<int, map<int, int>> dp;
int dfs(int p, int visit) {
  if (dp[p].count(visit))
    return dp[p][visit];
  else if (!visit) {
    bool f = false;
    rep(i, 4) if (!edge[p][i].empty()) f |= edge[p][i].front() == n;
    return dp[p][visit] = f ? 1 : 0;
    // return f ? 1 : 0;
  }

  int res = 0;
  rep(i, 4) {
    foreach (e, edge[p][i]) {
      if (*e == n)
        continue;
      if (!(visit & (1 << *e)))
        break;

      res += dfs(*e, visit ^ (1 << *e));
    }
  }

  return dp[p][visit] = res;
  // return res;
}
int main() {
  int h, w;
  while (scanf("%d%d", &w, &h), w | h) {
    rep(i, 24) rep(j, 4) edge[i][j].clear();

    pint church;
    vector<pint> pos;
    rep(i, h) {
      rep(j, w) {
        int t;
        scanf("%d", &t);
        if (t == 1)
          pos.push_back(pint(j, i));
        else if (t == 2)
          church = pint(j, i);
      }
    }
    n = pos.size();
    pos.push_back(church);

    rep(i, pos.size()) {
      vector<pint> hor, ver;
      rep(j, pos.size()) {
        if (pos[i].first == pos[j].first)
          ver.push_back(pint(pos[j].second, j));
        else if (pos[i].second == pos[j].second)
          hor.push_back(pint(pos[j].first, j));
      }
      sort(all(hor));
      sort(all(ver));

      foreach (it, hor) {
        if (it->first < pos[i].first)
          edge[i][3].push_front(it->second);
        else if (pos[i].first < it->first)
          edge[i][1].push_back(it->second);
      }
      foreach (it, ver) {
        if (it->first < pos[i].second)
          edge[i][2].push_front(it->second);
        else if (pos[i].second < it->first)
          edge[i][0].push_back(it->second);
      }
    }

    // rep (i, n + 1)
    //{
    //	printf(">%d: (%d, %d)\\n", i, pos[i].first, pos[i].second);
    //	rep (j, 4)
    //	{
    //		printf("%d: ", j);
    //		foreach (t, edge[i][j])
    //			printf("(%d, %d) ", pos[*t].first, pos[*t].second);
    //		puts("");
    //	}
    // }

    // memset(dp, ~0, sizeof(dp));
    dp.clear();
    int all_visit = (1 << n) - 1;
    printf("%d\\n", dfs(n, all_visit));

    // int s = 0;
    // rep (i, n)
    //	if (~dp[i][0])
    //		s += dp[i][0];
    // printf("%d\\n", s);
  }
}