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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>

using namespace std;

#define EPS (1e-10)
#define EQ(a, b) (abs((a) - (b)) < EPS)
#define EQV(a, b) (EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()))

typedef long long ll;

const int MAX_SIZE = 10000;

struct edge {
  int kind;
  int number;
};

const int INF = 100000000;
int main() {

  int w, h;

  // »ê¼êÌíÞÌm[hði[
  while (cin >> w >> h && !(w == 0 && h == 0)) {
    // dpe[u
    int dp[5][1001];
    // m[hÌÊu
    vector<edge> G[6][1001];
    char field[1001][1001];
    vector<pair<int, int>> p[6];
    pair<int, int> goal;
    pair<int, int> start;
    int minCost = INF;
    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < 1001; j++) {
        dp[i][j] = INF;
      }
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> field[i][j];
        if (field[i][j] == 'S') {
          start.first = i;
          start.second = j;
        } else if (field[i][j] == 'G') {
          goal.first = i;
          goal.second = j;
        } else if (field[i][j] != '.') {
          int num = field[i][j] - '0' - 1;
          p[num].push_back(make_pair(i, j));
        }
      }
    }

    // bool fin=false;
    // for(int i = 0; i < 5; i++){
    //	if(p[i].size()==0)
    //		fin=true;
    // }
    // if(fin){
    //	cout<<"NA"<<endl;
    //	continue;
    // }

    // iªX^[gn_
    int bestIdx = -1;
    for (int i = 0; i < 5; i++) {
      for (int j = 0; j < 5; j++) {
        fill(dp[j], dp[j] + 1001, INF);
      }
      for (int j = 0; j < p[(i + 1) % 5].size(); j++) {
        // X^[g©çÌ£
        dp[(i + 1) % 5][j] = abs(start.first - p[(i + 1) % 5][j].first) +
                             abs(start.second - p[(i + 1) % 5][j].second);
      }
      // jª¡Ìm[h
      for (int j = i + 1; j < i + 4; j++) {
        // Ü¸æÌm[hðßA»±ÉÎµÄÚ®ðs¤B
        for (int l = 0; l < p[(j + 1) % 5].size(); l++) {
          for (int k = 0; k < p[j % 5].size(); k++) {
            dp[(j + 1) % 5][l] =
                min(dp[(j + 1) % 5][l],
                    dp[j % 5][k] +
                        abs(p[j % 5][k].first - p[(j + 1) % 5][l].first) +
                        abs(p[j % 5][k].second - p[(j + 1) % 5][l].second));
          }
        }
      }
      // ÅãÉS[ÜÅÌRXgªÅZÈàÌðßé
      for (int j = 0; j < p[(i + 4) % 5].size(); j++) {
        if (minCost > dp[(i + 4) % 5][j] +
                          abs(goal.first - p[(i + 4) % 5][j].first) +
                          abs(goal.second - p[(i + 4) % 5][j].second)) {
          minCost = dp[(i + 4) % 5][j] +
                    abs(goal.first - p[(i + 4) % 5][j].first) +
                    abs(goal.second - p[(i + 4) % 5][j].second);
          bestIdx = i + 1;
        }
      }
    }
    if (bestIdx != -1)
      cout << bestIdx << " " << minCost << endl;
    else
      cout << "NA" << endl;
  }
  return 0;
}

// struct edge{
//	int kind;
//	int number;
//	int cost;
//};
//
//// m[hÌÊu
// vector<edge> G[6][1001];
// int d[6][1001][32];
// const int INF = 1000000000;
//
//
// class Situation{
// public:
//	Situation(int _cost,int _kind,int _number,int _used){
//		cost = _cost;
//		kind=_kind;
//		used = _used;
//		number=_number;
//	}
//
//	Situation();
//
//	int cost;
//	int kind;
//	int number;
//	int used;
//
//	bool operator<(const Situation &sit)const{
//		return sit.cost < (this->cost);
//	}
// };
//
// void dijkstra(int init){
//	priority_queue<Situation> que;
//
//	for(int i = 0; i < 6; i++)
//		for(int j = 0; j < 1001; j++)
//			for(int k = 0; k < 32; k++)
//				d[i][j][k]=INF;
//
//	d[init][0][1<<init]=0;
//
//	que.push(Situation(0,init,0,1<<init));
//	while(!que.empty()){
//		Situation p = que.top();
//		que.pop();
//		int k = p.kind;
//		int used=p.used;
//		int number=p.number;
//
//		if(d[k][number][used]<p.cost)
//			continue;
//		for(int i = 0; i < G[k][number].size(); i++){
//			edge e = G[k][number][i];
//			if(d[k][number][used]+e.cost<d[e.kind][e.number][used|(1<<e.kind)]){
//				d[e.kind][e.number][used|(1<<e.kind)]=d[k][number][used]+e.cost;
//				que.push(Situation(d[e.kind][e.number][used|(1<<e.kind)],e.kind,e.number,used|(1<<e.kind)));
//			}
//		}
//	}
// }
//
// struct info{
//	int x,y;
//	char kind;
// };
//
//
// int main(){
//
//	int w,h;
//	while(cin>>w>>h&&!(w==0&&h==0)){
//		int ct[6];
//		char field[1001][1001];
//		int cs[1001][1001];
//		pair<int,int> ctt[6][1001];
//		memset(cs,0,sizeof(cs));
//
//		for(int i = 0; i < 6; i++)
//			ct[i]=0;
//
//		vector<info> place;
//		pair<int,int> goal;
//		for(int i = 0; i < h; i++){
//			for(int j = 0; j < w; j++){
//				cin>>field[i][j];
//				if(field[i][j]!='.'&&field[i][j]!='G'&&field[i][j]!='S'){
//					info inf;
//					inf.x=j;
//					inf.y=i;
//					inf.kind=field[i][j];
//					place.push_back(inf);
//					ct[inf.kind-'0'-1]++;
//					cs[inf.y][inf.x]=ct[inf.kind-'0'-1];
//					ctt[inf.kind-'0'-1][ct[inf.kind-'0'-1]].first=i;
//					ctt[inf.kind-'0'-1][ct[inf.kind-'0'-1]].second=j;
//				}
//				else if(field[i][j]=='G'){
//					goal.first=i;
//					goal.second=j;
//				}
//				else if(field[i][j]=='S'){
//					info inf;
//					inf.x=j;
//					inf.y=i;
//					inf.kind='S';
//					place.push_back(inf);
//					cs[inf.y][inf.x]=0;
//				}
//			}
//		}
//
//		for(int i = 0; i < place.size(); i++){
//			for(int j = 0; j < place.size(); j++){
//				if(i!=j){
//					int
//dist=abs(place[i].y-place[j].y)+abs(place[i].x-place[j].x);
//					if(place[i].kind=='S'){
//						//
//ÇêðàÁÄX^[g·é© 						for(int k = 0; k < 5; k++){
//							edge in;
//							in.kind=place[j].kind-'0'-1;
//							in.cost=dist;
//							in.number=cs[place[j].y][place[j].x];
//							if((place[j].kind-'0'-1)==(k+1)%5)
//								G[k][0].push_back(in);
//						}
//					}
//					else{
//						if(place[j].kind=='S')
//							continue;
//
//						//
//ÇÌóÔÅü©¤© 						edge e;
//						e.number=cs[place[j].y][place[j].x];
//						e.cost=dist;
//						e.kind=place[j].kind-'0'-1;
//						int toKind=e.kind;
//						if(((place[i].kind-'0'-1)+1)%5==toKind){
//							G[place[i].kind-'0'-1][cs[place[i].y][place[i].x]].push_back(e);
//						}
//					}
//				}
//			}
//		}
//		int minCost=INF;
//		int idx;
//		// startn_ð¢­Â©·
//		for(int i = 0; i < 5; i++){
//			dijkstra(i);
//			for(int j = 0; j < 1001; j++){
//				for(int k = 0; k < 5; k++){
//					pair<int,int> p = ctt[k][j];
//					int
//dist=abs(p.first-goal.first)+abs(p.second-goal.second);
//					if(minCost>d[k][j][31]+dist){
//						minCost=min(minCost,d[k][j][31]+dist);
//						idx=i;
//					}
//				}
//			}
//
//		}
//		if(minCost==INF)
//			cout<<"NA"<<endl;
//		else
//			cout<<idx+1<<" "<<minCost<<endl;
//
//		for(int i = 0; i < 6; i++)
//			for(int j = 0; j < 1001;j++)
//				G[i][j].clear();
//	}
//
//	return 0;
// }

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>

using namespace std;

#define EPS (1e-10)
#define EQ(a, b) (abs((a) - (b)) < EPS)
#define EQV(a, b) (EQ((a).real(), (b).real()) && EQ((a).imag(), (b).imag()))

typedef long long ll;

const int MAX_SIZE = 10000;

struct edge {
  int kind;
  int number;
  int cost;
};

// ツノツーツドツづ個暗環置
vector<edge> G[6][1001];
int d[6][1001][32];
const int INF = 1000000000;

class Situation {
public:
  Situation(int _cost, int _kind, int _number, int _used) {
    cost = _cost;
    kind = _kind;
    used = _used;
    number = _number;
  }

  Situation();

  int cost;
  int kind;
  int number;
  int used;

  bool operator<(const Situation &sit) const { return sit.cost < (this->cost); }
};

void dijkstra(int init) {
  priority_queue<Situation> que;

  for (int i = 0; i < 6; i++)
    for (int j = 0; j < 1001; j++)
      for (int k = 0; k < 32; k++)
        d[i][j][k] = INF;
  d[init][0][1 << init] = 0;

  que.push(Situation(0, init, 0, 1 << init));
  while (!que.empty()) {
    Situation p = que.top();
    que.pop();
    int k = p.kind;
    int used = p.used;
    int number = p.number;

    if (d[k][number][used] < p.cost) {
      continue;
    }
    for (int i = 0; i < G[k][number].size(); i++) {
      edge e = G[k][number][i];
      if (d[k][number][used] + e.cost <
          d[e.kind][e.number][used | (1 << e.kind)]) {
        d[e.kind][e.number][used | (1 << e.kind)] = d[k][number][used] + e.cost;
        que.push(Situation(d[e.kind][e.number][used | (1 << e.kind)], e.kind,
                           e.number, used | (1 << e.kind)));
      }
    }
  }
}

struct info {
  int x, y;
  char kind;
};

int main() {

  int w, h;
  while (cin >> w >> h && !(w == 0 && h == 0)) {
    int ct[6];
    char field[1001][1001];
    int cs[1001][1001];
    pair<int, int> ctt[6][1001];
    memset(cs, 0, sizeof(cs));

    for (int i = 0; i < 6; i++)
      ct[i] = 0;

    vector<info> place;
    pair<int, int> goal;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> field[i][j];
        if (field[i][j] != '.' && field[i][j] != 'G' && field[i][j] != 'S') {
          info inf;
          inf.x = j;
          inf.y = i;
          inf.kind = field[i][j];
          place.push_back(inf);
          ct[inf.kind - '0' - 1]++;
          cs[inf.y][inf.x] = ct[inf.kind - '0' - 1];
          ctt[inf.kind - '0' - 1][ct[inf.kind - '0' - 1]].first = i;
          ctt[inf.kind - '0' - 1][ct[inf.kind - '0' - 1]].second = j;
        } else if (field[i][j] == 'G') {
          goal.first = i;
          goal.second = j;
        } else if (field[i][j] == 'S') {
          info inf;
          inf.x = j;
          inf.y = i;
          inf.kind = 'S';
          place.push_back(inf);
          cs[inf.y][inf.x] = 0;
        }
      }
    }

    for (int i = 0; i < place.size(); i++) {
      for (int j = 0; j < place.size(); j++) {
        if (i != j) {
          int dist =
              abs(place[i].y - place[j].y) + abs(place[i].x - place[j].x);
          if (place[i].kind == 'S') {
            // ツづづェツづーツづ^[g·é©
            for (int k = 0; k < 5; k++) {
              edge in;
              in.kind = place[j].kind - '0' - 1;
              in.cost = dist;
              in.number = cs[place[j].y][place[j].x];
              if ((place[j].kind - '0' - 1) == (k + 1) % 5)
                G[k][0].push_back(in);
            }
          } else {
            if (place[j].kind == 'S')
              continue;

            // ÇÌóÔÅü©¤©
            edge e;
            e.number = cs[place[j].y][place[j].x];
            e.cost = dist;
            e.kind = place[j].kind - '0' - 1;
            int toKind = e.kind;
            if (((place[i].kind - '0' - 1) + 1) % 5 == toKind) {
              G[place[i].kind - '0' - 1][cs[place[i].y][place[i].x]].push_back(
                  e);
            }
          }
        }
      }
    }
    int minCost = INF;
    int idx;
    // startn_ð¢­Â©·
    for (int i = 0; i < 5; i++) {
      dijkstra(i);
      for (int j = 0; j < 1001; j++) {
        for (int k = 0; k < 5; k++) {
          pair<int, int> p = ctt[k][j];
          int dist = abs(p.first - goal.first) + abs(p.second - goal.second);
          if (minCost > d[k][j][31] + dist) {
            minCost = min(minCost, d[k][j][31] + dist);
            idx = i;
          }
        }
      }
    }
    if (minCost == INF)
      cout << "NA" << endl;
    else {
      cout << idx + 1 << " " << minCost << endl;
    }
    for (int i = 0; i < 6; i++)
      for (int j = 0; j < 1001; j++)
        G[i][j].clear();
  }

  return 0;
}