Problem:
Acrophobia
C: 高所恐怖症
高杉やよいは，超売れっ子アイドルである．
そんな彼女には，1つ苦手なものがある．
高いところだ・・・．彼女は，極度の高所恐怖症なのである．
彼女は今回，プロデューサーの不手際により，バラエティ番組で次のようなチャレンジに挑戦することになってしまった．
今回のロケは，とある忍者屋敷のとある一室で行われる．
この部屋の床には，正方形のタイルが敷き詰められており，いくつかのタイルが抜け落ちて穴になっている．
この穴から落ちると数メートル下の池にまっさかさまである．
やよいのチャレンジ内容は，この部屋の指定された場所からスタートし，部屋の中に置かれた全ての巻物を回収し，ゴール地点まで持っていくことである．
やよいは，部屋の中を以下のルールに従って移動できる．
あるタイルから隣のタイルへ移動するとき，上下左右のタイルにのみ移動することができる．
穴に近くない場合，隣のタイルへ移動するためには，1秒だけ時間がかかる．
穴に近づいた場合，やよいは怖がってしまい図C-1のように移動時間がかかる．例えば，図中の矢印のように，[2][2]から[1][2]へ移動するためには，3秒かかる．
複数の穴が近くにある場合，最も近くにある穴に対して怖がる．
巻物を取るためにかかる時間は，0と仮定してよい．
図C-1: 穴の近くの移動時間
やよいは，なるべく早くこのチャレンジを終わらせたいと考えている．
あなたの仕事は，このチャレンジを終了するための最短時間を求めるプログラムを書き，やよいを助けてあげることである．
Input
忍者屋敷の床情報が与えられる．
まず，1行目に部屋の大きさを表す，
W
と
H
がスペース区切りで入力される(2 <=
W
,
H
<= 100)．
続く
H
行の各行には，
W
文字の文字列が入力される．
床情報を表す文字には，以下の種類がある．
'.' : 歩ける床
'#' : 穴
'S' : やよいが開始時に立っている場所
'G' : やよいが辿りつくべき場所
'M' : 巻物が置いてある場所
'S'と'G'と'M'は，歩ける床である．
'S'と'G'はそれぞれ，部屋の中にちょうど1個存在する．全ての巻物が揃っていない状態でゴールを通過しても構わない．
'M'は，部屋の中に最小で1個，最大で5個存在する．
Output
全ての巻物を集めて，スタートからゴールへたどり着くための最短タイムを1行に出力せよ．入力データには，必ずそのようなルートがあると仮定してよい．
行の最後には，改行を出力すること．
Sample Input 1
3 4
S.M
...
...
M.G
Sample Output 1
9
Sample Input 2
4 4
S..M
....
...#
#..G
Sample Output 2
18
Sample Input 3
11 7
M.........M
...........
...#.S.#...
...........
...#.G.#...
...........
M.........M
Sample Output 3
62

Submitted solutions:

code_snippet: #include "bits/stdc++.h" 

using namespace std;

vector<vector<int> > cst(110, vector<int>(110, 1));    
int dist[110][110];
int n, m;

struct node
{
    int x, y, d;
};

void dejkstra(int x, int y)
{
    queue<node> q;
    node p = {x,y,0};
    q.push(p); dist[x][y] = 0;
    int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1};
    while(!q.empty())
    {
        p = q.front(); q.pop();
        if(dist[p.x][p.y] < p.d) continue;
        for(int i = 0; i < 4; i++)
        {
            int nx = p.x + dx[i];
            int ny = p.y + dy[i];
            if(nx < 0 || ny < 0 || cst[nx][ny] == 4 || ny >= m || nx >= n) continue;
            int best = p.d + cst[p.x][p.y];
            if(dist[nx][ny] > best)
            {
                dist[nx][ny] = best;
                node l = {nx,ny,best};
                q.push(l);
            }
        }
    }
}

int main()
{
    cin >> m >> n;
    char a[n][m];
    int xS, yS, xG, yG; 
    for(int i = 0; i < n; i++)
        for(int j = 0;j < m;j ++) cin >> a[i][j];

    vector<pair<int, int> > M;
    
    for(int i =0 ; i< n;i++)
    {
        for(int j = 0;j < m; j++)
        {
            if(a[i][j] == '#')
            {
                for(int x = i - 2; x <= i + 2; x++)
                for(int y = j - 2; y <= j + 2; y++)
                if(x >= 0 && y >= 0)
                cst[x][y] = max(cst[x][y], 4 - max(abs(x - i), abs(y - j)));
            }
            if(a[i][j] == 'M') M.push_back(make_pair(i, j));
            if(a[i][j] == 'S') xS = i, yS = j;
            if(a[i][j] == 'G') xG = i, yG = j;
        }
    } 
    
    int k = M.size();
    vector<int> perm;
    int ans = 1e9;
    
    for(int i = 0;i < k; i++) perm.push_back(i);
    do{
        vector<pair<int, int> > p;
        p.push_back(make_pair(xS,yS));
        for(auto it : perm) p.push_back(M[it]);
        p.push_back(make_pair(xG,yG));
        
        int sum = 0;
        for(int i = 0;i < p.size()-1; i++)
        {
            for(int i = 0; i < 110;i ++) for(int j = 0;j < 110; j++) dist[i][j] = 1e9;
            dejkstra(p[i].first, p[i].second);
            sum += dist[p[i+1].first][p[i+1].second];
        }   
        ans = min(ans, sum);

    } while(next_permutation(perm.begin(), perm.end()));
    cout << ans << "\n";
}
accuracy: 1
time_ms: 230
memory_kb: 3552
final_rank: 16

code_snippet: #include "bits/stdc++.h" 

using namespace std;

vector<vector<int> > cst(110, vector<int>(110, 1));    
int dist[110][110];
int n, m;

struct node
{
    int x, y, d;
};

void dejkstra(int x, int y)
{
    queue<node> q;
    node p = {x,y,0};
    q.push(p); dist[x][y] = 0;
    int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1};
    while(!q.empty())
    {
        p = q.front(); q.pop();
        if(dist[p.x][p.y] < p.d) continue;
        for(int i = 0; i < 4; i++)
        {
            int nx = p.x + dx[i];
            int ny = p.y + dy[i];
            if(nx < 0 || ny < 0 || cst[nx][ny] == 4 || ny >= m || nx >= n) continue;
            int best = p.d + cst[p.x][p.y];
            if(dist[nx][ny] > best)
            {
                dist[nx][ny] = best;
                node l = {nx,ny,best};
                q.push(l);
            }
        }
    }
}

int main()
{
    cin >> m >> n;
    char a[n][m];
    int xS, yS, xG, yG; 
    for(int i = 0; i < n; i++)
        for(int j = 0;j < m;j ++) cin >> a[i][j];

    vector<pair<int, int> > M;
    
    for(int i =0 ; i< n;i++)
    {
        for(int j = 0;j < m; j++)
        {
            if(a[i][j] == '#')
            {
                for(int x = i - 2; x <= i + 2; x++)
                for(int y = j - 2; y <= j + 2; y++)
                if(x >= 0 && y >= 0)
                cst[x][y] = max(cst[x][y], 4 - max(abs(x - i), abs(y - j)));
            }
            if(a[i][j] == 'M') M.push_back(make_pair(i, j));
            if(a[i][j] == 'S') xS = i, yS = j;
            if(a[i][j] == 'G') xG = i, yG = j;
        }
    } 
    
    int k = M.size();
    vector<int> perm;
    int ans = 1e9;
    
    for(int i = 0;i < k; i++) perm.push_back(i);
    do{
        vector<pair<int, int> > p;
        p.push_back(make_pair(xS,yS));
        for(auto it : perm) p.push_back(M[it]);
        p.push_back(make_pair(xG,yG));
        
        int sum = 0;
        for(int i = 0;i < p.size()-1; i++)
        {
            for(int i = 0; i < 110;i ++) for(int j = 0;j < 110; j++) dist[i][j] = 1e9;
            dejkstra(p[i].first, p[i].second);
            sum += dist[p[i+1].first][p[i+1].second];
        }   
        ans = min(ans, sum);

    } while(next_permutation(perm.begin(), perm.end()));
    cout << ans << endl;
}
accuracy: 1
time_ms: 240
memory_kb: 3552
final_rank: 17

code_snippet: #include "bits/stdc++.h" 

using namespace std;

vector<vector<int> > cst(110, vector<int>(110, 1));    
int dist[110][110];
int n, m;

struct node
{
    int x, y, d;
};

void dejkstra(int x, int y)
{
    queue<node> q;
    node p = {x,y,0};
    q.push(p); dist[x][y] = 0;
    int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1};
    while(!q.empty())
    {
        p = q.front(); q.pop();
        if(dist[p.x][p.y] < p.d) continue;
        for(int i = 0; i < 4; i++)
        {
            int nx = p.x + dx[i];
            int ny = p.y + dy[i];
            //cout << p.x << ' ' << p.y << ' ' << ny << ' ' << nx << endl;
            if(nx < 0 || ny < 0 || cst[nx][ny] == 4 || ny >= m || nx >= n) continue;
            int best = p.d + cst[p.x][p.y];
            //cout << nx << ' ' << ny << ' ' << best << ' ' << p.x << ' ' << p.y << ' ' << endl;
            if(dist[nx][ny] > best)
            {
                dist[nx][ny] = best;
                node l = {nx,ny,best};
                q.push(l);
            }
        }
    }
}

int main()
{
    cin >> m >> n;
    char a[n][m];
    int xS, yS, xG, yG; 
    for(int i = 0; i < n; i++)
        for(int j = 0;j < m;j ++) cin >> a[i][j];

    vector<pair<int, int> > M;
    
    for(int i =0 ; i< n;i++)
    {
        for(int j = 0;j < m; j++)
        {
            int f = 0;
            if(a[i][j] == '#')
            {
                for(int x = i - 2; x <= i + 2; x++)
                for(int y = j - 2; y <= j + 2; y++)
                if(x >= 0 && y >= 0)
                cst[x][y] = max(cst[x][y], 4 - max(abs(x - i), abs(y - j)));
            }
            if(a[i][j] == 'M') M.push_back(make_pair(i, j));
            if(a[i][j] == 'S') xS = i, yS = j;
            if(a[i][j] == 'G') xG = i, yG = j;
        }
    }
    
    int k = M.size();
    vector<int> perm;
    // for(int i = 0;i < n; i++){
    // for(int j = 0;j < m ;j++)
    //     cout << cst[i][j] << ' ';
    //     cout << endl;
    // }
    int ans = 1e9;
    
    for(int i = 0;i < k; i++) perm.push_back(i);
    do{
        vector<pair<int, int> > p;
        p.push_back(make_pair(xS,yS));
        for(auto it : perm) p.push_back(M[it]);
        p.push_back(make_pair(xG,yG));
       // for(auto it : p) cout << it.first << ' ' << it.second << endl;
       // cout << endl;
        int sum = 0;
        for(int i = 0;i < p.size()-1; i++)
        {
            for(int i = 0; i < 110;i ++) for(int j = 0;j < 110; j++) dist[i][j] = 1e9;
            dejkstra(p[i].first, p[i].second);
            // for(int i = 0;i < n; i++){
            // for(int j = 0;j < m ;j++)
            //     cout << dist[i][j] << ' ';
            //     cout << endl;
            // } cout << endl;
            sum += dist[p[i+1].first][p[i+1].second];
        }   
        ans = min(ans, sum);

    } while(next_permutation(perm.begin(), perm.end()));

    cout << ans << endl;
}
accuracy: 1
time_ms: 240
memory_kb: 3556
final_rank: 18

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template_no_Ruby.cpp"
#include <bits/stdc++.h>
#line 4 "/home/yuruhiya/programming/library/template/constants.cpp"
#include <string_view>
#line 7 "/home/yuruhiya/programming/library/template/constants.cpp"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1000000000;
constexpr long long inf_ll = 1000000000000000000ll, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
namespace CharacterClass {
	constexpr string_view
	    digit = "0123456789",
	    xdigit = "0123456789ABCDEFabcdef", lower = "abcdefghijklmnopqrstuvwxyz",
	    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
	    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    alnum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    word = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz",
	    punct = R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
	    graph =
	        R"(!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    print =
	        R"( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    blank = " \t", space = " \t\n\r\f\v";
}  // namespace CharacterClass
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = gc(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void put(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(bool v) const {
		put(v ? B.t : B.f);
	}
	void put(vector<bool>::reference v) const {
		put(v ? B.t : B.f);
	}
	void put(char v) const {
		putchar_unlocked(v);
	}
	void put(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void put(double v) const {
		printf("%.20f", v);
	}
	void put(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void put(const T& v) const {
		cout << v;
	}
	template <class T, class U> void put(const pair<T, U>& v) const {
		put(v.first);
		put(D.d);
		put(v.second);
	}
	template <class InputIterater>
	void put_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) put(D.d);
			put(*i);
		}
	}
	template <class T> void put(const vector<T>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T, size_t N> void put(const array<T, N>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T> void put(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) put(D.l);
			put(v[i]);
		}
	}

	Output() = default;
	Output(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Output& operator()() {
		put(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		put(h);
		put(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		put(h);
		put(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Output& range(const InputIterator& begin, const InputIterator& end) {
		put_range(begin, end);
		put(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 6 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T> T div_ceil(T n, T m) {
	return (n + m - 1) / m;
}
template <class T> T div_ceil2(T n, T m) {
	return div_ceil(n, m) * m;
}
template <class T> T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T> T middle(const T& l, const T& r) {
	return l + (r - l) / 2;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool in_range(const T& v, const T& min, const T& max) {
	return min <= v && v < max;
}
template <class T> bool in_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> T BIT(int b) {
	return T(1) << b;
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
template <class T, class U> T Pow(T a, U n) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U> T Powmod(T a, U n, T mod) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 7 "/home/yuruhiya/programming/library/template/template_no_Ruby.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 5 "/home/yuruhiya/programming/library/Utility/Point.cpp"
#include <optional>
#line 9 "/home/yuruhiya/programming/library/Utility/Point.cpp"
using namespace std;

struct Point {
	static int H, W;
	static const vector<Point> direction;
	using direction_iterator = vector<Point>::const_iterator;
	static void set_range(int _H, int _W) {
		H = _H;
		W = _W;
	}
	static constexpr Point zero() {
		return {0, 0};
	}
	static constexpr Point one() {
		return {1, 1};
	}
	static constexpr Point L() {
		return {-1, 0};
	}
	static constexpr Point R() {
		return {1, 0};
	}
	static constexpr Point U() {
		return {0, -1};
	}
	static constexpr Point D() {
		return {0, 1};
	}
	static constexpr Point LU() {
		return {-1, -1};
	}
	static constexpr Point LD() {
		return {-1, 1};
	}
	static constexpr Point RU() {
		return {1, -1};
	}
	static constexpr Point RD() {
		return {1, 1};
	}

	int x, y;
	constexpr Point() : x(0), y(0) {}
	constexpr Point(int _x, int _y) : x(_x), y(_y) {}
	constexpr Point(const pair<int, int>& xy) : x(xy.first), y(xy.second) {}
	Point(int n) : x(n % W), y(n / W) {}
	constexpr Point operator+() const {
		return *this;
	}
	constexpr Point operator-() const {
		return {-x, -y};
	}
	constexpr Point operator+(const Point& p) const {
		return Point(*this) += p;
	}
	constexpr Point operator-(const Point& p) const {
		return Point(*this) -= p;
	}
	constexpr Point operator*(const Point& p) const {
		return Point(*this) *= p;
	}
	constexpr Point operator/(const Point& p) const {
		return Point(*this) /= p;
	}
	constexpr Point operator%(const Point& p) const {
		return Point(*this) %= p;
	}
	constexpr Point operator+(int n) const {
		return Point(*this) += n;
	}
	constexpr Point operator-(int n) const {
		return Point(*this) -= n;
	}
	constexpr Point operator*(int n) const {
		return Point(*this) *= n;
	}
	constexpr Point operator/(int n) const {
		return Point(*this) /= n;
	}
	constexpr Point operator%(int n) const {
		return Point(*this) %= n;
	}
	constexpr Point& operator+=(const Point& p) {
		x += p.x;
		y += p.y;
		return *this;
	}
	constexpr Point& operator-=(const Point& p) {
		x -= p.x;
		y -= p.y;
		return *this;
	}
	constexpr Point& operator*=(const Point& p) {
		x *= p.x;
		y *= p.y;
		return *this;
	}
	constexpr Point& operator/=(const Point& p) {
		x /= p.x;
		y /= p.y;
		return *this;
	}
	constexpr Point& operator%=(const Point& p) {
		x %= p.x;
		y %= p.y;
		return *this;
	}
	constexpr Point& operator+=(int n) {
		x += n;
		y += n;
		return *this;
	}
	constexpr Point& operator-=(int n) {
		x -= n;
		y -= n;
		return *this;
	}
	constexpr Point& operator*=(int n) {
		x *= n;
		y *= n;
		return *this;
	}
	constexpr Point& operator/=(int n) {
		x /= n;
		y /= n;
		return *this;
	}
	constexpr Point& operator%=(int n) {
		x %= n;
		y %= n;
		return *this;
	}
	constexpr bool operator==(const Point& p) const {
		return x == p.x && y == p.y;
	}
	constexpr bool operator!=(const Point& p) const {
		return x != p.x || y != p.y;
	}
	bool operator<(const Point& p) const {
		return to_i() < p.to_i();
	}
	bool operator<=(const Point& p) const {
		return to_i() <= p.to_i();
	}
	bool operator>(const Point& p) const {
		return to_i() > p.to_i();
	}
	bool operator>=(const Point& p) const {
		return to_i() >= p.to_i();
	}
	constexpr int operator[](int i) const {
		return i == 0 ? x : i == 1 ? y : 0;
	}
	constexpr bool in_range(int height, int width) const {
		return 0 <= x && x < width && 0 <= y && y < height;
	}
	bool in_range() const {
		return in_range(H, W);
	}
	int to_i() const {
		return x + y * W;
	}
	constexpr pair<int, int> to_pair() const {
		return {x, y};
	}
	constexpr int manhattan_distance(const Point& p) const {
		return abs(x - p.x) + abs(y - p.y);
	}
	constexpr int chebyshev_distance(const Point& p) const {
		return max(abs(x - p.x), abs(y - p.y));
	}
	constexpr int distance_square(const Point& p) const {
		return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
	}
	template <class Real> constexpr Real distance(const Point& p) const {
		return sqrt(static_cast<Real>(distance_square(p)));
	}
	constexpr Point absolute(const Point& p) const {
		return absolute(*this - p);
	}
	constexpr Point absolute() const {
		return {abs(x), abs(y)};
	}
	Point& swap() {
		std::swap(x, y);
		return *this;
	}

	class enumrate_adjacent_helper {
		shared_ptr<Point> p;
		direction_iterator first, last;

		class iterator {
			shared_ptr<Point> p;
			direction_iterator it;

		public:
			iterator(shared_ptr<Point> _p, direction_iterator _it) : p(_p), it(_it) {}
			Point operator*() const {
				return *p + *it;
			}
			iterator& operator++() {
				++it;
				return *this;
			}
			bool operator!=(iterator other) const {
				return it != other.it;
			}
		};

	public:
		enumrate_adjacent_helper(shared_ptr<Point> _p, direction_iterator _first,
		                         direction_iterator _last)
		    : p(_p), first(_first), last(_last) {}
		iterator begin() const {
			return iterator(p, first);
		}
		iterator end() const {
			return iterator(p, last);
		}
	};
	auto enumrate_adjacent(direction_iterator first, direction_iterator last) const {
		return enumrate_adjacent_helper(make_shared<Point>(*this), first, last);
	}
	auto adjacent4() const {
		return enumrate_adjacent(direction.begin(), direction.begin() + 4);
	}
	auto adjacent8() const {
		return enumrate_adjacent(direction.begin(), direction.begin() + 8);
	}

	class enumrate_adj_in_range_helper {
		shared_ptr<Point> p;
		direction_iterator first, last;

		class sentinel {};
		class iterator {
			shared_ptr<Point> p;
			direction_iterator first, last;

			void increment_until_in_range() {
				for (; first != last; ++first) {
					if ((*p + *first).in_range()) return;
				}
			}

		public:
			iterator(shared_ptr<Point> _p, direction_iterator _first,
			         direction_iterator _last)
			    : p(_p), first(_first), last(_last) {
				increment_until_in_range();
			}
			Point operator*() const {
				return *p + *first;
			}
			iterator& operator++() {
				++first;
				increment_until_in_range();
				return *this;
			}
			bool operator!=(sentinel other) const {
				return first != last;
			}
		};

	public:
		enumrate_adj_in_range_helper(shared_ptr<Point> _p, direction_iterator _first,
		                             direction_iterator _last)
		    : p(_p), first(_first), last(_last) {}
		iterator begin() const {
			return iterator(p, first, last);
		}
		sentinel end() const {
			return sentinel();
		}
	};
	template <class InputIterator>
	auto enumrate_adj_in_range(InputIterator first, InputIterator last) const {
		return enumrate_adj_in_range_helper(make_shared<Point>(*this), first, last);
	}
	auto adj4_in_range() const {
		return enumrate_adj_in_range(direction.begin(), direction.begin() + 4);
	}
	auto adj8_in_range() const {
		return enumrate_adj_in_range(direction.begin(), direction.end());
	}

	constexpr Point left() const {
		return {x - 1, y};
	}
	constexpr Point right() const {
		return {x + 1, y};
	}
	constexpr Point up() const {
		return {x, y - 1};
	}
	constexpr Point down() const {
		return {x, y + 1};
	}
	Point succ() const {
		if (x != W - 1) {
			return {x + 1, y};
		} else {
			return {0, y + 1};
		}
	}
	Point pred() const {
		if (x != 0) {
			return {x - 1, y};
		} else {
			return {W - 1, y - 1};
		}
	}
	constexpr Point moved(char c) const {
		return Point(*this).move(c);
	}
	constexpr Point& move(char c) {
		switch (c) {
			case 'L':
			case 'l':
			case 'W':
			case '>':
				x--;
				break;
			case 'R':
			case 'r':
			case 'E':
			case '<':
				x++;
				break;
			case 'U':
			case 'u':
			case 'N':
			case '^':
				y--;
				break;
			case 'D':
			case 'd':
			case 'S':
			case 'v':
				y++;
				break;
		}
		return *this;
	}
	constexpr Point rotate90() const {
		return {y, -x};
	}
	constexpr Point rotate180() const {
		return {-x, -y};
	}
	constexpr Point rotate270() const {
		return {-y, x};
	}
	char to_direction_char(string_view lrud = "LRUD") const {
		assert(4 <= lrud.size() && lrud.size() <= 5);
		if (y == 0 && x < 0) {
			return lrud[0];
		} else if (y == 0 && x > 0) {
			return lrud[1];
		} else if (x == 0 && y < 0) {
			return lrud[2];
		} else if (x == 0 && y > 0) {
			return lrud[3];
		} else if (lrud.size() == 5) {
			return lrud[4];
		} else {
			assert(false);
		}
	}

	static Point to_direction(char c, string_view lrud = "LRUD") {
		assert(lrud.size() == 4);
		if (c == lrud[0]) {
			return L();
		} else if (c == lrud[1]) {
			return R();
		} else if (c == lrud[2]) {
			return U();
		} else if (c == lrud[3]) {
			return D();
		} else {
			return zero();
		}
	}

	template <class T, class value_type = typename T::value_type::value_type>
	static optional<Point> find(const T& grid, const value_type& val) {
		assert(static_cast<int>(grid.size()) == H);
		for (int i = 0; i < H; ++i) {
			assert(static_cast<int>(grid[i].size()) == W);
			for (int j = 0; j < W; ++j) {
				if (grid[i][j] == val) {
					return Point(j, i);
				}
			}
		}
		return nullopt;
	}
	template <class T, class Predicate>
	static optional<Point> find_if(const T& grid, Predicate pred) {
		assert(static_cast<int>(grid.size()) == H);
		for (int i = 0; i < H; ++i) {
			assert(static_cast<int>(grid[i].size()) == W);
			for (int j = 0; j < W; ++j) {
				if (pred(grid[i][j])) {
					return Point(j, i);
				}
			}
		}
		return nullopt;
	}
	template <class T, class value_type = typename T::value_type::value_type>
	static optional<Point> find_one(const T& grid, const value_type& val) {
		assert(static_cast<int>(grid.size()) == H);
		optional<Point> result;
		for (int i = 0; i < H; ++i) {
			assert(static_cast<int>(grid[i].size()) == W);
			for (int j = 0; j < W; ++j) {
				if (grid[i][j] == val) {
					assert(!result);
					result = Point(j, i);
				}
			}
		}
		return result;
	}
	template <class T, class value_type = typename T::value_type::value_type>
	static vector<Point> find_all(const T& grid, const value_type& val) {
		assert(static_cast<int>(grid.size()) == H);
		vector<Point> result;
		for (int i = 0; i < H; ++i) {
			assert(static_cast<int>(grid[i].size()) == W);
			for (int j = 0; j < W; ++j) {
				if (grid[i][j] == val) {
					result.emplace_back(j, i);
				}
			}
		}
		return result;
	}

	static auto enumrate_2D_points() {
		class enumrate_2D_points_helper {
		public:
			class iterator {
				Point p;

			public:
				iterator(const Point& _p) : p(_p) {}
				Point operator*() const {
					return p;
				}
				iterator& operator++() {
					p = p.succ();
					return *this;
				}
				iterator& operator--() {
					p = p.pred();
					return *this;
				}
				bool operator!=(iterator other) const {
					return p != other.p;
				}
			};
			iterator begin() const {
				return iterator(Point(0, 0));
			}
			iterator end() const {
				return iterator(Point(0, H));
			}
		};
		return enumrate_2D_points_helper();
	}

	friend ostream& operator<<(ostream& os, const Point& p) {
		return os << '(' << p.x << ", " << p.y << ')';
	}
	friend istream& operator>>(istream& is, Point& p) {
		return is >> p.y >> p.x;
	}
};
int Point::H, Point::W;
const vector<Point> Point::direction{Point::R(),  Point::D(),  Point::U(),  Point::L(),
                                     Point::RD(), Point::LU(), Point::RU(), Point::LD()};
#line 5 "/home/yuruhiya/programming/library/Graph/GraphTemplate.cpp"
using namespace std;

using Weight = long long;
constexpr Weight INF = numeric_limits<Weight>::max();
struct Edge {
	int to;
	Weight cost;
	Edge() : to(-1), cost(-1) {}
	Edge(int _to, Weight _cost = 1) : to(_to), cost(_cost) {}
	friend bool operator<(const Edge& e1, const Edge& e2) {
		return e1.cost < e2.cost;
	}
	friend bool operator>(const Edge& e1, const Edge& e2) {
		return e1.cost > e2.cost;
	}
	friend ostream& operator<<(ostream& os, const Edge& e) {
		return os << "->" << e.to << '(' << e.cost << ')';
	}
};
using Graph = vector<vector<Edge>>;
struct Edge2 {
	int from, to;
	Weight cost;
	Edge2() : from(-1), to(-1), cost(0) {}
	Edge2(int _from, int _to, Weight _cost) : from(_from), to(_to), cost(_cost) {}
	friend bool operator<(const Edge2& e1, const Edge2& e2) {
		return e1.cost < e2.cost;
	}
	friend bool operator>(const Edge2& e1, const Edge2& e2) {
		return e1.cost > e2.cost;
	}
	friend ostream& operator<<(ostream& os, const Edge2& e) {
		return os << e.from << "->" << e.to << '(' << e.cost << ')';
	}
};
using Edges = vector<Edge2>;
using Matrix = vector<vector<Weight>>;
#line 5 "/home/yuruhiya/programming/library/Graph/Dijkstra.cpp"
using namespace std;

vector<Weight> Dijkstra(const Graph& graph, int s) {
	int V = graph.size();
	vector<Weight> dist(V, INF);
	dist[s] = 0;
	priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
	pq.emplace(s, 0);
	while (!pq.empty()) {
		Edge p = pq.top();
		pq.pop();
		int v = p.to;
		if (dist[v] < p.cost) continue;
		for (auto e : graph[v]) {
			if (dist[e.to] > dist[v] + e.cost) {
				dist[e.to] = dist[v] + e.cost;
				pq.emplace(e.to, dist[e.to]);
			}
		}
	}
	return dist;
}
#line 4 "a.cpp"

int main() {
	ini(w, h);
	VS s = in[h];
	Point::set_range(h, w);

	Point start = *Point::find_one(s, 'S'), goal = *Point::find_one(s, 'G');
	vector<Point> passing = Point::find_all(s, 'M');
	passing.insert(passing.begin(), start);
	passing.push_back(goal);
	vector<Point> holes = Point::find_all(s, '#');

	Graph g(h * w);
	for (const auto& p : Point::enumrate_2D_points()) {
		if (s[p.y][p.x] == '#') continue;
		ll time = 1;
		for (const auto& hole : holes) {
			chmax<ll>(time, 4 - p.chebyshev_distance(hole));
		}
		for (const auto& q : p.adj4_in_range()) {
			if (s[q.y][q.x] != '#') {
				g[p.to_i()].emplace_back(q.to_i(), time);
			}
		}
	}

	int m = passing.size();
	auto dist = make_vector<ll>({m, m});
	rep(i, m) {
		auto dist_i = Dijkstra(g, passing[i].to_i());
		rep(j, m) {
			dist[i][j] = dist_i[passing[j].to_i()];
		}
	}
	dump(passing, dist);

	ll ans = inf_ll;
	VI perm(m - 2);
	iota(all(perm), 1);
	do {
		VI p{0};
		p.insert(p.end(), all(perm));
		p.push_back(m - 1);
		ll d = 0;
		rep(i, m - 1) {
			d += dist[p[i]][p[i + 1]];
		}
		chmin(ans, d);
	} while (next_permutation(all(perm)));
	out(ans);
}
accuracy: 1
time_ms: 10
memory_kb: 4156
final_rank: 4

code_snippet: #include <iostream>
#include <numeric>
#include <queue>
#include <cstring>
#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
#include <limits.h>
using namespace std;
typedef vector<int> vi;
typedef long long ll;
typedef long long ll;
typedef vector<ll> vll;
const int inf=10000000;
int H,W,startx,starty,goalx,goaly;
string board[105];
int cost[105][105];
int d[105][105];
bool visited[150][105];
int dx8[]={-1,-1,0,1,1,1,0,-1};
int dy8[]={0,1,1,1,0,-1,-1,-1};
int dy[]={0,1,0,-1};
int dx[]={-1,0,1,0};

typedef pair<int,int> P;
typedef pair<int,pair<int,int> > PP;

void costset(int sx,int sy,int times)
{
  if(times==2) return;
  int nowx=sx;
  int nowy=sy;
  int cos=3-times;
  for(int k=0;k<8;k++)
    {
      int nx=nowx+dx8[k];
      int ny=nowy+dy8[k];
      if(nx<0 || W<=nx || ny<0 || H<=ny) continue;
      cost[ny][nx]=max(cost[ny][nx],cos);
      costset(nx,ny,times+1);
    }
}

int solve(int sx,int sy,int gx,int gy)
{
  for(int i=0;i<H;i++)
    {
      for(int j=0;j<W;j++)
	{
	  d[i][j]=inf;
	}
    }
  d[sy][sx]=0;
  priority_queue<PP,vector<PP> ,greater<PP>> p;
  p.push(PP(0,P(sy,sx)));
  int nowy,nowx;
  while(!p.empty())
    {
      PP now=p.top();p.pop();
      nowy=now.second.first;
      nowx=now.second.second;
      if(nowx==gx && nowy==gy) break;
      for(int k=0;k<4;k++)
	{
	  int ny=nowy+dy[k];
	  int nx=nowx+dx[k];
	  if(ny<0 || H<=ny || nx<0 || W<=nx || board[ny][nx]=='#') continue;
	  if(d[nowy][nowx]+cost[nowy][nowx]>=d[ny][nx]) continue;
	  if(d[ny][nx]==inf || d[ny][nx]>d[nowy][nowx]+cost[nowy][nowx])
	    {
	      d[ny][nx]=d[nowy][nowx]+cost[nowy][nowx];
	      p.push(PP(d[ny][nx],P(ny,nx)));
	    }
	}
    }
  return d[gy][gx];
}

int main(int argc,char const* argv[])
{
  int ans=20000000;
  int scroll=0;
  int pat=1;
  int graph[10][10];
  for(int i=0;i<10;i++)
    {
      for(int j=0;j<10;j++)
	{
	  graph[i][j]=inf;
	}
    }
  vector<P> route;
  cin >> W >> H;
  for(int i=0;i<H;i++)
    {
      cin >> board[i];
    }
  for(int i=0;i<H;i++)
    {
      for(int j=0;j<W;j++)
	{
	  cost[i][j]=1;
	  if(board[i][j]=='M') route.push_back(P(i,j));
	  if(board[i][j]=='G') {goaly=i;goalx=j;}
	  if(board[i][j]=='S') {starty=i;startx=j;}
	}
    }
  sort(route.begin(),route.end());
  for(int i=0;i<H;i++)
    {
      for(int j=0;j<W;j++)
	{
	  if(board[i][j]=='#')
	    {
	      costset(j,i,0);
	    }
	  if(board[i][j]=='M')
	    {
	      scroll++;
	    }
	}
    }
  for(int i=0;i<route.size();i++)
    {
      graph[0][i+1]=solve(startx,starty,route[i].second,route[i].first);
      graph[i+1][6]=solve(route[i].second,route[i].first,goalx,goaly);					      
      for(int j=0;j<route.size();j++)
	{
	  if(i==j) continue;
	  int stx=route[i].second;
	  int sty=route[i].first;
	  int gox=route[j].second;
	  int goy=route[j].first;
	  graph[i+1][j+1]=solve(stx,sty,gox,goy);
	  //graph[j+1][i+1]=graph[i+1][j+1];
	}
    }
   vector<int> walk(scroll);
   iota(walk.begin(),walk.end(),1);
   do
     {
       int tmp=0;
       int prev=0;
       int to=0;
       for(auto x:walk) 
	 {
	   to=x;
	   tmp+=graph[prev][to];
	   prev=x;
	 }
       tmp+=graph[to][6];
       ans=min(ans,tmp);
     } while(next_permutation(walk.begin(),walk.end()));
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3280
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define INF 1000000000

int di[4] = {0, -1, 0, 1};
int dj[4] = {1, 0, -1, 0};

vector<int> dijk(int s, int v, vector<vector<pair<int, int> > > adjlist){
    
    priority_queue <pair<int, int> > wait;
    vector<int> result(v, INF);

    //スタート地点を追加
    result[s] = 0;
    wait.push(make_pair(0, s));

    //ダイクストラ本体
    while(!wait.empty()){    //waitが空になるまで

        int nowpoint = wait.top().second;
        int nowcost = -wait.top().first;
        wait.pop();

        if(result[nowpoint] < nowcost) continue;


        //今いる頂点と隣接しているすべての頂点をなめる
        for(int i = 0; i < adjlist[nowpoint].size(); i++){

            int nextpoint = adjlist[nowpoint][i].second;
            int nextcost = nowcost + adjlist[nowpoint][i].first;
            //現時点より安く到達できそうであれば、結果を更新して優先度付きキューに格納
            if(result[nextpoint] > nextcost){
                result[nextpoint] = nextcost;
                wait.push(make_pair(-nextcost, nextpoint));
            }
        }
    }
    
    return result;         //結果列を返す
}

int main(){

    int h, w; cin >> w >> h;
    int si, sj, gi, gj;
    vector<vector<int> > gold(h + 2, vector<int> (w + 2, 0));
    vector<vector<int> > canGo(h + 2, vector<int> (w + 2, 0));

    int cnt = 0;
    for(int i = 1; i <= h; i++){
        for(int j = 1; j <= w; j++){
            char in; cin >> in;
            if(in == '#'){
                canGo[i][j] = 4;
            }else{
                canGo[i][j] = 1;

                if(in == 'S'){
                    si = i;
                    sj = j;
                }

                if(in == 'G'){
                    gi = i;
                    gj = j;
                }

                if(in == 'M'){
                    cnt++;
                    gold[i][j] = cnt;
                }
            }
        }
    }

    int Map[110][110][(1 << 5)];

    int node = 0;
    for(int i = 1; i <= h; i++){
        for(int j = 1; j <= w; j++){
            for(int bit = 0; bit < (1 << 5); bit++){
                Map[i][j][bit] = node;
                node++;
            }
        }
    }

    //cout << cnt << " " << node << endl;

    for(int i = 1; i <= h; i++){
        for(int j = 1; j <= w; j++){

            //あなあなら
            if(canGo[i][j] == 4){
                

                for(int k = i - 2; k <= i + 2; k++){
                    for(int l = j - 2; l <= j + 2; l++){
                        if(k < 1 || h < k || l < 1 || w < l) continue;

                        canGo[k][l] = max(canGo[k][l], 2);
                    }
                }

                for(int k = i - 1; k <= i + 1; k++){
                    for(int l = j - 1; l <= j + 1; l++){
                        if(k < 1 || h < k || l < 1 || w < l) continue;

                        canGo[k][l] = max(canGo[k][l], 3);
                    }
                }
            }
        }
    }

    vector<vector<pair<int, int> > > adjlist(node);

    for(int i = 1; i <= h; i++){
        for(int j = 1; j <= w; j++){
            for(int bit = 0; bit < (1 << 5); bit++){

                //アナなら
                if(canGo[i][j] == 4) continue;

                int cost = canGo[i][j];
                int now_node = Map[i][j][bit];

                for(int h = 0; h < 4; h++){
                    int ni = i + di[h];
                    int nj = j + dj[h];

                    if(canGo[ni][nj] == 4) continue;
                    if(canGo[ni][nj] == 0) continue;

                    int next_bit = bit;
                    if(gold[ni][nj] != 0){
                        int idx = gold[ni][nj] - 1;
                        next_bit = next_bit & (~((1 << idx)));
                    }

                    int next_node = Map[ni][nj][next_bit];

                    adjlist[now_node].push_back(make_pair(cost, next_node));
                }
            }
        }
    }

    vector<int> result(node);
    int S = Map[si][sj][(1 << cnt) - 1];
    int G = Map[gi][gj][0];
    result = dijk(S, node, adjlist);
    cout << result[G] << endl;

    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 46408
final_rank: 20

code_snippet: #include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
#include <deque>
#include <tuple>
#include <iostream>
using namespace std;

const int INF = 1 << 28;
int H, W;
int sx, sy, gx, gy;
int board[110][110], dist[10][10], dp[1 << 10][10], rec[110][110];

int nxt[] = {0, 1, 1, 2, 3};
int dx[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};

int ex[] = {0, 0, 1, -1};
int ey[] = {1, -1, 0, 0};

void get_board(deque< pair<int, int> > holes) {
  int N = holes.size();

  for(int i=0; i<N; i++) {
    int ix = holes[i].first, iy = holes[i].second;
    queue< pair<int, int> > que;
    que.push(make_pair(ix, iy));

    while(que.size()) {
      int cx, cy; tie(cx, cy) = que.front(); que.pop();
      for(int k=0; k<8; k++) {
        int nx = cx + dx[k], ny = cy + dy[k];
        if(nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
        if(board[nx][ny] == 4) continue;

        int cst = nxt[ board[cx][cy] ];
        if(cst > board[nx][ny]) {
          board[nx][ny] = cst;
          que.push(make_pair(nx, ny));
        }
      }
    }
  }
}

struct Elem {
  int x, y, cost;
  bool operator<(const Elem &e) const {
    return cost > e.cost;
  }
};

void bfs(deque< pair<int, int> > treasures, int id) {
  fill(rec[0], rec[110], INF);

  int ix, iy; tie(ix, iy) = treasures[id];
  priority_queue<Elem> que;
  rec[ix][iy] = 0;
  que.push(Elem{ix, iy, 0});

  while(que.size()) {
    Elem cur = que.top(); que.pop();
    int x = cur.x, y = cur.y, cst = cur.cost;

    for(int k=0; k<4; k++) {
      int nx = x + ex[k], ny = y + ey[k];
      if(nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
      if(board[nx][ny] == INF) continue;

      int n_cost = cst + max(1, board[x][y]);
      if(rec[nx][ny] > n_cost) {
        rec[nx][ny] = n_cost;
        que.push(Elem{nx, ny, n_cost});
      }
    }
  }

  int N = treasures.size();
  for(int i=0; i<N; i++) {
    int tx, ty; tie(tx, ty) = treasures[i];
    // printf("tx = %d, ty = %d, cost = %d\n", tx, ty, rec[tx][ty]);
    dist[id][i] = rec[tx][ty];
  }
}

int main() {
  cin >> W >> H;

  deque< pair<int, int> > holes, treasures;
  for(int i=0; i<H; i++) {
    for(int j=0; j<W; j++) {
      char c; cin >> c;
      if(c == 'S') {
        sx = i, sy = j;
      }
      else if(c == 'G') {
        gx = i, gy = j;
      }
      else if(c == '#') {
        holes.push_back(make_pair(i, j));
        board[i][j] = 4;
      }
      else if(c == 'M') {
        treasures.push_back(make_pair(i, j));
      }
    }
  }

  get_board(holes);
  for(int i=0; i<holes.size(); i++) {
    int x, y; tie(x, y) = holes[i];
    board[x][y] = INF;
  }


  /*
  // debug
  for(int i=0; i<H; i++) {
    for(int j=0; j<W; j++) {
      cout << board[i][j];
    }
    cout << endl;
  }
  */
  
  
  int N = treasures.size();
  int si = 0, gi = N + 1;
  treasures.push_front(make_pair(sx, sy));
  treasures.push_back (make_pair(gx, gy));
  N += 2;
  
  for(int i=0; i<N; i++) {
    bfs(treasures, i);
  }

  /*
  // debug
  for(int i=0; i<N; i++) {
    for(int j=0; j<N; j++) {
      cout << dist[i][j] << " ";
    }
    cout << endl;
  }
  */

  int fullbit = (1<<N) - 1;

  fill(dp[0], dp[1 << 10], INF);
  dp[1][0] = 0;
  for(int bit=0; bit<(1<<N); bit++) {
    for(int i=0; i<N; i++) {
      for(int k=0; k<N; k++) {
        if(!(bit >> i & 1)) continue;
        if(bit >> k & 1) continue;
        int nbit = bit | (1 << k);
        // if(k == N-1 && nbit != fullbit) continue;

        int cost = dist[i][k];
        dp[nbit][k] = min(dp[nbit][k], dp[bit][i] + cost);
      }
    }
  }

  int ans = dp[fullbit][N-1];
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3296
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

int W, H, cost[102][102], N, hx[5], hy[5], sx, sy, gx, gy;
string grid[102];

const int dx[4] = {0,1,0,-1}, Dx[8] = {0,1,1,1,0,-1,-1,-1};
const int dy[4] = {1,0,-1,0}, Dy[8] = {1,1,0,-1,-1,-1,0,1};
bool in_range(int x, int y) { return 0 <= x && x < W && 0 <= y && y < H; }

void pre() {
	memset(cost, -1, sizeof(cost));
	
	N = 0;
	for (int y=0; y<H; ++y) for (int x=0; x<W; ++x) {
		if (grid[y][x] == '#') cost[y][x] = 100;
		if (grid[y][x] == 'M') {
			hx[N] = x;
			hy[N] = y;
			++N;
		}
		if (grid[y][x] == 'S') sx = x, sy = y;
		if (grid[y][x] == 'G') gx = x, gy = y;
	}
	
	for (int y=0; y<H; ++y) for (int x=0; x<W; ++x) {
		if (cost[y][x] < 0) {
			bool hole_flag = false;
			for (int d=0; d<8; ++d) {
				int nx = x + Dx[d], ny = y + Dy[d];
				if (!in_range(nx, ny)) continue;
				hole_flag |= (grid[ny][nx] == '#');
			}
			if (hole_flag) cost[y][x] = 3;
		}
	}
	
	for (int y=0; y<H; ++y) for (int x=0; x<W; ++x) {
		if (cost[y][x] < 0) {
			int max_c = -1;
			for (int d=0; d<8; ++d) {
				int nx = x + Dx[d], ny = y + Dy[d];
				if (!in_range(nx, ny)) continue;
				max_c = max(max_c, cost[ny][nx]);
			}
			cost[y][x] = max_c - 1;
		}
	}
	
	for (int y=0; y<H; ++y) for (int x=0; x<W; ++x) if (cost[y][x] <= 0) cost[y][x] = 1;
}

	
struct State {
	int x, y, c;
	bool operator > (const State& s) const { return c > s.c; }
};

int dst[102][102];

int dijkstra(int ax, int ay, int bx, int by) {
	memset(dst, -1, sizeof(dst));
	
	priority_queue< State, vector< State >, greater< State > > que;
	que.push(State{ax, ay, 0});
	dst[ay][ax] = 0;
	
	while (!que.empty()) {
		State s = que.top(); que.pop();
		if (dst[s.y][s.x] < s.c) continue;
		for (int d=0; d<4; ++d) {
			int nx = s.x + dx[d], ny = s.y + dy[d], nc = s.c + cost[s.y][s.x];
			if (!in_range(nx, ny)) continue;
			if (grid[ny][nx] == '#') continue;
			if (dst[ny][nx] == -1 || dst[ny][nx] > nc) {
				dst[ny][nx] = nc;
				que.push(State{nx, ny, nc});
			}
		}
	}
	
	return dst[by][bx];
}

int main() {
	cin >> W >> H;
	for (int y=0; y<H; ++y) cin >> grid[y];
	
	pre();
	
	vector< int > order;
	for (int i=0; i<N; ++i) order.push_back(i);
	
	int ans = 1L << 30;
	do {
		int sum = dijkstra(sx, sy, hx[order[0]], hy[order[0]]);
		for (int i=0; i<N-1; ++i) {
			int a = order[i], b = order[i+1];
			sum += dijkstra(hx[a], hy[a], hx[b], hy[b]);
		}
		sum += dijkstra(hx[order[N-1]], hy[order[N-1]], gx, gy);
		ans = min(ans, sum);
	} while (next_permutation(order.begin(), order.end()));
	cout << ans << endl;
}
accuracy: 1
time_ms: 410
memory_kb: 3316
final_rank: 19

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
 
using namespace std;
 
#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
 
template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }
 
typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx3[4] = {1, 0, -1, 0};
int dy3[4] = {0, 1, 0, -1};
int dx[8] = {1, 0, -1, -1, -1, 0, 1, 1};
int dy[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
int dx2[16] = {0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1};
int dy2[16] = {2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1, 0, 1, 2, 2};
struct state{
  int x, y, S;
  int c;
  state() {}
  state(int x, int y, int S, int c) : x(x), y(y), S(S), c(c) {}
  bool operator < (const state& s) const {
    return c > s.c; //rev
  }
};
 
int main(){
  int W, H;
  while(cin>>W>>H && (W||H)){
    vector<string> grid(H);
    REP(y, H) cin>>grid[y];
    int cnt = 0;
    REP(y, H)REP(x, W)if(grid[y][x] == 'M'){
      grid[y][x] = cnt + '0';
      cnt++;
    }
    const int goalS = (1<<cnt) - 1;
    int move[100][100] = {};
    REP(y, H)REP(x, W) move[y][x] = 1;
    REP(y, H)REP(x, W){
      if(grid[y][x] == '#'){
        REP(r, 8){
          int nx = x + dx[r], ny = y + dy[r];
          if(nx >= 0 && ny >= 0 && nx < W && ny < H){
            move[ny][nx] = 3;
          }
        }
        REP(r, 16){
          int nx = x + dx2[r], ny = y + dy2[r];
          if(nx >= 0 && ny >= 0 && nx < W && ny < H){
            move[ny][nx] = max(move[ny][nx], 2);
          }
        }
      }
    }
    int dist[1<<5][100][100];
    priority_queue<state> que;
    REP(y, H)REP(x, W)REP(i, 1<<5)dist[i][y][x] = INF;
    REP(y, H)REP(x, W)if(grid[y][x] == 'S'){
      dist[0][y][x] = 0;
      que.push(state(x, y, 0, 0));
    }
    int ans = INF;
    while(!que.empty()){
      state s = que.top(); que.pop();
      if(s.S == goalS && grid[s.y][s.x] == 'G'){
        ans = s.c;
        break;
      }
      REP(r, 4){
        int nx = s.x + dx3[r];
        int ny = s.y + dy3[r];
        if(!(nx >= 0 && ny >= 0 && nx < W && ny < H)) continue;
        if(grid[ny][nx] == '#') continue;
        int nc = s.c + move[s.y][s.x];
        int nS = s.S;
        if(grid[ny][nx] <= '5' && grid[ny][nx] >= '0'){
          nS = nS | (1<<(grid[ny][nx]-'0'));
        }
        if(dist[nS][ny][nx] > nc){
          dist[nS][ny][nx] = nc;
          que.push(state(nx, ny, nS, nc));
        }
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4504
final_rank: 5

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
struct aa {
	int x;
	int y;
	bitset<5>gets;
	int cost;
};
class Compare {
public:
	bool operator()(const aa&l, const aa&r) {
		return l.cost>r.cost;
	}
};

int main() {
	int H,W;cin>>W>>H;
	vector<vector<int>>field(H,vector<int>(W,1));
	vector<pair<int,int>>makis;
	int sx, sy, gx, gy;
	{
		vector<pair<int, int>>holes;
		for (int i = 0; i < H; ++i) {
			string st; cin >> st;
			for (int j = 0; j < W; ++j) {
				char ch(st[j]);
				if (ch == 'S') {
					sx = j;
					sy = i;
				}
				else if (ch == 'G') {
					gx = j;
					gy = i;
				}
				else if (ch == '#') {
					holes.push_back(make_pair(j, i));
				}
				else if (ch == 'M') {
					makis.push_back(make_pair(j,i));
				}
			}
		}
		for (auto hole : holes) {
			for (int y = 0; y < H; ++y) {
				for (int x = 0; x < W; ++x) {
					int x_dis = abs(x - hole.first);
					int y_dis = abs(y - hole.second);
					int dis = max(x_dis, y_dis);
					if (dis == 0) {
						field[y][x] = max(field[y][x],10000);
					}
					else if (dis <= 3) {
						field[y][x] =max(field[y][x],4-dis);
					}
				}
			}
		}
	}

	priority_queue<aa,vector<aa>,Compare>que;

	que.push(aa{ sx,sy,bitset<5>(),0 });
	vector<vector<vector<int>>>memo(W,vector<vector<int>>(H,vector<int>(32,1e9)));
	memo[sx][sy][0]=0;
	int dx[4] = { -1,0,1,0 };
	int dy[4] = { 0,1,0,-1 };
	int ans=-1;
	while (!que.empty()) {
		auto atop(que.top());
		const int now_x=atop.x;
		const int now_y=atop.y;
		const bitset<5>gets(atop.gets);
		const int now_cost=atop.cost;

		if (now_x == gx&&now_y == gy&&gets.count() == makis.size()) {
			ans=now_cost;
			break;
		}
		que.pop();
		for (int way = 0; way < 4; ++way) {
			const int next_x=now_x+dx[way];
			const int next_y=now_y+dy[way];

			if (0 <= next_x&&next_x < W&&next_y < H && 0 <= next_y) {
				const int next_cost=now_cost+field[now_y][now_x];
				auto next_gets(gets);
				for (int i = 0; i < makis.size(); ++i) {
					if (next_x == makis[i].first&&next_y == makis[i].second) {
						next_gets[i]=true;
					}
				}
				if (memo[next_x][next_y][next_gets.to_ulong()] > next_cost) {
					memo[next_x][next_y][next_gets.to_ulong()]=next_cost;
					que.push(aa{ next_x,next_y,next_gets,next_cost });
				}
			}
		}
	}
	cout<<ans<<endl;
	

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 5576
final_rank: 13

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Hole{
	int row,col;
};

struct Info{
	Info(int arg_row,int arg_col,int arg_state,int arg_total_cost){
		row = arg_row;
		col = arg_col;
		state = arg_state;
		total_cost = arg_total_cost;
	}

	int row,col,state,total_cost;
};

int H,W;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}

int main(){

	int POW[6];

	for(int i = 0; i < 6; i++)POW[i] = pow(2,i);

	scanf("%d %d",&W,&H);

	char map[H][W+1];

	int hole_num = 0;
	Hole hole[10000];

	int makimono_num = 0;

	int start_row,start_col,goal_row,goal_col;

	for(int i = 0; i < H; i++){
		scanf("%s",map[i]);
		for(int k = 0; k < W; k++){
			switch(map[i][k]){
			case 'S':
				start_row = i;
				start_col = k;
				map[i][k] = '.';
				break;
			case 'G':
				goal_row = i;
				goal_col = k;
				map[i][k] = '.';
				break;
			case 'M':
				map[i][k] = '0' + makimono_num;
				makimono_num++;
				break;
			case '#':
				hole[hole_num].row = i;
				hole[hole_num].col = k;
				hole_num++;
				break;
			}
		}
	}

	int move_cost[H][W];

	for(int i = 0; i < H; i++){
		for(int k = 0; k < W; k++)move_cost[i][k] = 1;
	}

	for(int i = 0; i < hole_num; i++){
		for(int row = 0; row < H; row++){
			for(int col = 0; col < W; col++){
				if(map[row][col] == '#')continue;
				move_cost[row][col] = max(move_cost[row][col],4-max(abs(hole[i].row-row),abs(hole[i].col-col)));
			}
		}
	}

	int limit = POW[makimono_num];

	int dp[H][W][limit];

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int state = 0; state < limit; state++)dp[row][col][state] = BIG_NUM;
		}
	}

	queue<Info> Q;

	Q.push(Info(start_row,start_col,0,0));

	int next_row,next_col,next_state;

	while(!Q.empty()){

		if(Q.front().state == limit-1 && Q.front().row == goal_row && Q.front().col == goal_col){
			Q.pop();
		}else if(Q.front().total_cost > dp[Q.front().row][Q.front().col][Q.front().state]){
			Q.pop();
		}else{
			for(int i = 0; i < 4; i++){
				next_row = Q.front().row + diff_row[i];
				next_col = Q.front().col + diff_col[i];

				if(rangeCheck(next_row,next_col) == false || map[next_row][next_col] == '#')continue;

				next_state = Q.front().state;
				if(map[next_row][next_col] >= '0' && map[next_row][next_col] <= '4'){
					if(!(Q.front().state & (1 << (map[next_row][next_col]-'0')))){
						next_state += POW[map[next_row][next_col]-'0'];
					}
				}

				if(dp[next_row][next_col][next_state] > Q.front().total_cost+move_cost[Q.front().row][Q.front().col]){
					dp[next_row][next_col][next_state] = Q.front().total_cost+move_cost[Q.front().row][Q.front().col];
					Q.push(Info(next_row,next_col,next_state,dp[next_row][next_col][next_state]));
				}
			}
			Q.pop();
		}
	}

	printf("%d\n",dp[goal_row][goal_col][limit-1]);

	return 0;

}
accuracy: 1
time_ms: 50
memory_kb: 4776
final_rank: 11

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define INF 1<<25
using namespace std;
string s[101];
typedef pair<int,int> P;
int w,h,a[101][101],sx,sy,gx,gy;
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int dx1[]={1,1,1,0,0,-1,-1,-1};
int dy1[]={1,0,-1,1,-1,1,0,-1};
int dx2[]={2,2,2,2,2,1,1,0,0,-1,-1,-2,-2,-2,-2,-2};
int dy2[]={2,1,0,-1,-2,2,-2,2,-2,2,-2,2,1,0,-1,-2};
vector<P>G[10001];
vector<int>maki;
void make_map(int y,int x){
  a[y][x]=INF;
  r(i,8){
    int xx=x+dx1[i];
    int yy=y+dy1[i];
    if(xx<0||yy<0||yy>=h||xx>=w)continue;
    if(a[yy][xx]<3)a[yy][xx]=3;
  }
  r(i,16){
    int xx=x+dx2[i];
    int yy=y+dy2[i];
    if(xx<0||yy<0||yy>=h||xx>=w)continue;
    if(a[yy][xx]<2)a[yy][xx]=2;
  }
}
int d[10001];
void dijkstra(int s){
  priority_queue<P,vector<P>,greater<P> >que;
  fill(d,d+10001,INF);
  d[s]=0;
  que.push(P(0,s));
  while(!que.empty()){
    P p=que.top();que.pop();
    int v=p.second;
    if(d[v]<p.first)continue;
    for(int i=0;i<G[v].size();i++){
      P e=G[v][i];
      if(d[e.first]>d[v]+e.second){
        d[e.first]=d[v]+e.second;
        que.push(P(d[e.first],e.first));
      }
    }
  }
}
int ans=INF,used[101]={},koko;
int dis[101][101];
void dfs(int depth,int dista,int cur){
  if(depth==koko-1){
    //cout<<dista<<endl;
    ans=min(ans,dista);
    return;
  }
  if(depth<koko-2){
    for(int i=1;i<koko-1;i++)
      if(!used[i]){
      used[i]=1;
      dfs(depth+1,dista+dis[cur][i],i);
      used[i]=0;
    }
  }
  else{
    used[cur]=1;
    dfs(depth+1,dista+dis[cur][koko-1],cur);
    used[cur]=0;
  }
}
main(){
  r(i,101)r(j,101)a[i][j]=1;
  cin>>w>>h;
  r(i,h)cin>>s[i];
  r(i,h)r(j,w){
    if(s[i][j]=='#')make_map(i,j);
    if(s[i][j]=='S')sx=i*w+j;
    if(s[i][j]=='G')gx=i*w+j;
    if(s[i][j]=='M')maki.push_back(i*w+j);
  }
  r(i,h)r(j,w)r(k,4){
    int xx=j+dx[k];
    int yy=i+dy[k];
    if(xx<0||yy<0||yy>=h||xx>=w)continue;
    if(k==0)G[i*w+j].push_back(P(i*w+j+1,a[i][j]));
    if(k==1)G[i*w+j].push_back(P(i*w+j-1,a[i][j]));
    if(k==2)G[i*w+j].push_back(P(i*w+w+j,a[i][j]));
    if(k==3)G[i*w+j].push_back(P(i*w-w+j,a[i][j]));
  }
  int num=maki.size()+2;
  vector<int>ps;
  ps.push_back(sx);
  r(i,maki.size())ps.push_back(maki[i]);
  ps.push_back(gx);
  r(i,num){
    dijkstra(ps[i]);
    r(j,num)dis[i][j]=d[ps[j]];
  }
  koko=num;
  used[0]=1;
  dfs(0,0,0);
  cout<<ans<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 3944
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define all(v) begin(v), end(v)
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for(int i = (int)(s); i < (int)(n); i++)
#define min(...) min({__VA_ARGS__})
#define max(...) max({__VA_ARGS__})

template<class T1, class T2> void chmin(T1 &a, T2 b){if(a>b)a=b;}
template<class T1, class T2> void chmax(T1 &a, T2 b){if(a<b)a=b;}

using pint = pair<int, int>;
using tint = tuple<int, int, int>;
using vint = vector<int>;

const int inf = 1LL << 55;
const int mod = 1e9 + 7;

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int H, W;
  char mas[101][101];
  int sy, sx, gy, gx;
  int delay[101][101] = {{}};
  int maki = 0;
  map<pint, int> mp;

  auto in = [&](int y, int x) -> bool {
    return 0 <= y && y < H && 0 <= x && x < W;
  };

  cin >> W >> H;
  rep(i, H) rep(j, W) {
    cin >> mas[i][j];
    chmax(delay[i][j], 1);
    if(mas[i][j] == 'S') sy = i, sx = j;
    else if(mas[i][j] == 'G') gy = i, gx = j;
    else if(mas[i][j] == 'M') mp[make_pair(i, j)] = maki++;
    else if(mas[i][j] == '#') {
      delay[i][j] = inf;
      reps(k, 1, 4) {
	reps(l, -4+k, 4-k+1) {
	  if(in(i-4+k, j+l)) chmax(delay[i-4+k][j+l], k);
	  if(in(i+4-k, j+l)) chmax(delay[i+4-k][j+l], k);
	  if(in(i+l, j-4+k)) chmax(delay[i+l][j-4+k], k);
	  if(in(i+l, j+4-k)) chmax(delay[i+l][j+4-k], k);
	}
      }
    }
  }

  struct state {
    int y, x, bit, dist;
    state(int y = 0, int x = 0, int bit = 0, int dist = 0)
      :y(y), x(x), bit(bit), dist(dist){}
    bool operator < (const state& s) const {
      return dist > s.dist;
    }
  };

  priority_queue<state> que;
  int d[101][101][1<<5];
  int dy[] = {1, 0, -1, 0};
  int dx[] = {0, 1, 0, -1};

  que.emplace(sy, sx, 0, 0);
  rep(i, 101) rep(j, 101) rep(k, 1<<5) d[i][j][k] = inf;
  d[sy][sx][0] = 0;
  while(que.size()) {
    state st = que.top(); que.pop();
    int y = st.y, x = st.x, bit = st.bit, dist = st.dist;
    if(y == gy && x == gx && bit == (1<<maki)-1) {
      cout << dist << endl;
      return 0;
    }
    if(d[y][x][bit] < dist) continue;
    rep(i, 4) {
      int ny = y + dy[i], nx = x + dx[i], nbit = bit;
      if(!in(ny, nx) || mas[ny][nx] == '#') continue;
      if(mas[ny][nx] == 'M') nbit |= 1<<(mp[make_pair(ny, nx)]);
      if(dist + delay[y][x] < d[ny][nx][nbit]) {
	d[ny][nx][nbit] = dist + delay[y][x];
	que.emplace(ny, nx, nbit, d[ny][nx][nbit]);
      }
    }
  }

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5868
final_rank: 10

code_snippet: #include<bits/stdc++.h>
#define  f first 
#define  s second 
using namespace std;
typedef pair<int,int> P;
typedef pair<P,P> PP;
int w,h,c=1,sx,sy,gx,gy;
char mp[101][101];
int bt[101][101];
int cs[101][101];
int nn[5][5]=
  {{2,2,2,2,2},
   {2,3,3,3,2},
   {2,3,1e8,3,2},
   {2,3,3,3,2},
   {2,2,2,2,2}
  };
int used[100][101][101];
 
void nu(int x,int y){
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++){
      int nx=x+j-2,ny=y+i-2;
      if(nx<0||w<=nx||ny<0||h<=ny)continue;
      cs[ny][nx]=max(nn[i][j],cs[ny][nx]);
    }
}
 
int cal(){
  priority_queue<PP,vector<PP>,greater<PP> > Q;
  Q.push(PP(P(0,0),P(sx,sy)));
  int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
  while(!Q.empty()){
    PP p=Q.top();
    Q.pop();
    if(p.s.f==gx&&p.s.s==gy&&p.f.s==c-1)return p.f.f;
    if(used[p.f.s][p.s.s][p.s.f]==1)continue;
    used[p.f.s][p.s.s][p.s.f]=1;
    for(int i=0;i<4;i++){
      int nx=p.s.f+dx[i],ny=p.s.s+dy[i];
      int ncs=p.f.f+cs[p.s.s][p.s.f],nbt=p.f.s|bt[p.s.s][p.s.f];
      if(nx<0||w<=nx||ny<0||h<=ny)continue;
      Q.push(PP(P(ncs,nbt),P(nx,ny)));
    }
  }
}
 
 
int main(){
  cin>>w>>h;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++){
      cin>>mp[i][j];
      cs[i][j]=max(1,cs[i][j]);
      if(mp[i][j]=='M')bt[i][j]=c,c*=2;
      if(mp[i][j]=='#')nu(j,i);
      if(mp[i][j]=='S')sx=j,sy=i;
      if(mp[i][j]=='G')gx=j,gy=i;
    }
  cout<<cal()<<endl; 
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 8312
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef pair<P,P> PP;
int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1};
bool check(int n,int m,int x,int y) {return x>=0&&x<n&&y>=0&&y<m;}
 
int a[111][111],d[55][111][111];
map<P,int> ma;
int main() {
  int n,m;
  cin >> m >> n;
  string s[n];
  for(int i=0; i<n; i++) cin >> s[i];
  priority_queue<PP,vector<PP>,greater<PP> > que;
  for(int i=0; i<n; i++) {
    for(int j=0; j<m; j++) {
      a[i][j]=1;
      for(int k=0; k<(1<<5); k++) d[k][i][j]=1<<29;
      if(s[i][j]=='S') {
        d[0][i][j]=0;
        que.push(PP(P(0,0),P(i,j)));
      }
      if(s[i][j]=='M') {
        int k=ma.size();
        ma[P(i,j)]=k;
      }
      for(int k=-2; k<=2; k++) {
        for(int l=-2; l<=2; l++) {
          int x=i+k,y=j+l;
          if(!check(n,m,x,y)||s[x][y]!='#') continue;
          int d=max(abs(i-x),abs(j-y));
          if(d==1) a[i][j]=max(a[i][j],3);
          if(d==2) a[i][j]=max(a[i][j],2);
        }
      }
    }
  }
  while(!que.empty()) {
    PP p=que.top();que.pop();
    int xx=p.second.first,yy=p.second.second,cc=p.first.first,tt=p.first.second;
    if(s[xx][yy]=='G'&&tt==(1<<ma.size())-1) {
      cout << d[tt][xx][yy] << endl;
      return 0;
    }
    if(d[tt][xx][yy]<cc) continue;
    for(int i=0; i<4; i++) {
      int x=xx+dx[i],y=yy+dy[i];
      int t=tt;
      if(!check(n,m,x,y)||s[x][y]=='#') continue;
      if(s[x][y]=='M') t|=1<<ma[P(x,y)];
      if(d[t][x][y]<=d[tt][xx][yy]+a[xx][yy]) continue;
      d[t][x][y]=d[tt][xx][yy]+a[xx][yy];
      que.push(PP(P(d[t][x][y],t),P(x,y)));
    }
  }
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4840
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int sp[111][111];
int dp[111][111][1<<5];
int w,h;
int in(int y,int x){
  return 0<=y&&y<h&&0<=x&&x<w;
}
struct sta{
  int y,x,b,d;
  sta(){}
  sta(int y,int x,int b,int d):y(y),x(x),b(b),d(d){}
  bool operator<(const sta& a) const{
    return d>a.d;
  }
};
typedef pair<int,int> P;
int main(){
  memset(sp,0,sizeof(sp));
  memset(dp,-1,sizeof(dp));
  cin>>w>>h;
  string st[h];
  for(int i=0;i<h;i++) cin>>st[i];
  int sy,sx,gy,gx,n=0;
  map<P,int> m;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      sp[i][j]=max(sp[i][j],1);
      if(st[i][j]=='M') m[P(i,j)]=n++;
      if(st[i][j]=='S') sy=i,sx=j;
      if(st[i][j]=='G') gy=i,gx=j;
      if(st[i][j]=='#'){
    for(int k=1;k<=3;k++){
      for(int a=-(4-k);a<=4-k;a++){
        if(in(i-(4-k),j+a)) sp[i-(4-k)][j+a]=max(sp[i-(4-k)][j+a],k);
        if(in(i+(4-k),j+a)) sp[i+(4-k)][j+a]=max(sp[i+(4-k)][j+a],k);
        if(in(i+a,j-(4-k))) sp[i+a][j-(4-k)]=max(sp[i+a][j-(4-k)],k);
        if(in(i+a,j+(4-k))) sp[i+a][j+(4-k)]=max(sp[i+a][j+(4-k)],k);
      }
    }
      }
    }
  }
  /*//
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      cout<<sp[i][j];
    }
    cout<<endl;
  }
  //*/
  priority_queue<sta> q;
  q.push(sta(sy,sx,0,0));
  dp[sy][sx][0]=0;
  int ax[]={1,-1,0,0};
  int ay[]={0,0,1,-1};
  while(!q.empty()){
    sta s=q.top();q.pop();
    if(dp[s.y][s.x][s.b]<s.d) continue;
    //cout<<s.y<<" "<<s.x<<" "<<s.b<<" "<<s.d<<endl;
    for(int k=0;k<4;k++){
      int ny=s.y+ay[k],nx=s.x+ax[k],nb=s.b,nd=s.d+sp[s.y][s.x];
      if(!in(ny,nx)) continue;
      if(st[ny][nx]=='#') continue;
      if(m.count(P(ny,nx))) nb|=1<<m[P(ny,nx)];
      if(dp[ny][nx][nb]<0||dp[ny][nx][nb]>nd){
    dp[ny][nx][nb]=nd;
    q.push(sta(ny,nx,nb,nd));
      }
    }
  }
  cout<<dp[gy][gx][(1<<n)-1]<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4884
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define N 101
#define INF 1e9
using namespace std;
string mp[N];
int D[101][101][1<<5];
int used[101][101];
typedef pair<int,int> P;
typedef pair<P,P> PP;
int dx[] ={0,0,1,-1};
int dy[] ={1,-1,0,0};
int w,h;

void bfs(){
  memset(used,-1,sizeof(used));
  queue<P> Q;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)if(mp[i][j]=='#')Q.push(P(i,j)),used[i][j] = 0;
  
  while(!Q.empty()){
    P t = Q.front();Q.pop();
    int y = t.first;
    int x = t.second;
    for(int i=-1;i<=1;i++)
      for(int j=-1;j<=1;j++){
	if(i==0&&j==0)continue;
	int nx = x+i;
	int ny = y+j;
	if(nx<0||ny<0||nx>=w||ny>=h||used[ny][nx]!=-1)continue;
	used[ny][nx] = used[y][x] + 1;
	Q.push(P(ny,nx));
      }
  }

  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)if(used[i][j] == -1) used[i][j]=INF;
  
} 


int visited[N][N][1<<5];
int dijkstra(int sy,int sx){
  map<P,int> M;
  int cnt=0;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)if(mp[i][j] == 'M') M[P(i,j)] = cnt++;
  
  for(int i=0;i<101;i++)
    for(int j=0;j<101;j++)
      for(int k=0;k<(1<<5);k++) D[i][j][k] = INF;
  
  priority_queue<PP,vector<PP>,greater<PP> >Q;  
  Q.push(PP(P(0,sy),P(sx,0)));
  D[sy][sx][0] = 0;
 
  while(!Q.empty()){
    PP t = Q.top();Q.pop();
    int cost = t.first.first;
    int y = t.first.second;
    int x = t.second.first;
    int bit = t.second.second;
    if(mp[y][x] =='G' && bit==(1<<cnt)-1)return cost;
    if(D[y][x][bit]<cost||visited[y][x][bit]++) continue;
    
    for(int i=0;i<4;i++){
      int nx = x+dx[i];
      int ny = y+dy[i];
      int nbit = bit;
      int ncost = cost+max(1,4-used[y][x]);
      if(nx<0||ny<0||nx>=w||ny>=h||mp[ny][nx] == '#')continue;
      if(D[ny][nx][nbit]<=ncost||visited[ny][nx][nbit])continue;
      if(mp[ny][nx] == 'M') nbit |= 1<<(M[P(ny,nx)]); 
      Q.push(PP(P(ncost,ny),P(nx,nbit)));
      D[ny][nx][nbit] = ncost;
    }
  }
  assert(0);
}


int main(){

  cin>>w>>h;
  for(int i=0;i<h;i++) cin>>mp[i];

  bfs();
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(mp[i][j] == 'S') cout<<dijkstra(i,j)<<endl;

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5764
final_rank: 8

code_snippet: #include<bits/stdc++.h>
#define  f first 
#define  s second 
using namespace std;
typedef pair<int,int> P;
typedef pair<P,P> PP;
int w,h,c=1,sx,sy,gx,gy;
char mp[101][101];
int bt[101][101];
int cs[101][101];
int nn[5][5]=
  {{2,2,2,2,2},
   {2,3,3,3,2},
   {2,3,1e8,3,2},
   {2,3,3,3,2},
   {2,2,2,2,2}
  };
int used[100][101][101];

void nu(int x,int y){
  for(int i=0;i<5;i++)
    for(int j=0;j<5;j++){
      int nx=x+j-2,ny=y+i-2;
      if(nx<0||w<=nx||ny<0||h<=ny)continue;
      cs[ny][nx]=max(nn[i][j],cs[ny][nx]);
    }
}

int cal(){
  priority_queue<PP,vector<PP>,greater<PP> > Q;
  Q.push(PP(P(0,0),P(sx,sy)));
  int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
  while(!Q.empty()){
    PP p=Q.top();
    Q.pop();
    if(p.s.f==gx&&p.s.s==gy&&p.f.s==c-1)return p.f.f;
    if(used[p.f.s][p.s.s][p.s.f]==1)continue;
    used[p.f.s][p.s.s][p.s.f]=1;
    for(int i=0;i<4;i++){
      int nx=p.s.f+dx[i],ny=p.s.s+dy[i];
      int ncs=p.f.f+cs[p.s.s][p.s.f],nbt=p.f.s|bt[p.s.s][p.s.f];
      if(nx<0||w<=nx||ny<0||h<=ny)continue;
      Q.push(PP(P(ncs,nbt),P(nx,ny)));
    }
  }
}


int main(){
  cin>>w>>h;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++){
      cin>>mp[i][j];
      cs[i][j]=max(1,cs[i][j]);
      if(mp[i][j]=='M')bt[i][j]=c,c*=2;
      if(mp[i][j]=='#')nu(j,i);
      if(mp[i][j]=='S')sx=j,sy=i;
      if(mp[i][j]=='G')gx=j,gy=i;
    }
  cout<<cal()<<endl; 
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 8312
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int sp[111][111];
int dp[111][111][1<<5];
int w,h;
int in(int y,int x){
  return 0<=y&&y<h&&0<=x&&x<w;
}
struct sta{
  int y,x,b,d;
  sta(){}
  sta(int y,int x,int b,int d):y(y),x(x),b(b),d(d){}
  bool operator<(const sta& a) const{
    return d>a.d;
  }
};
typedef pair<int,int> P;
int main(){
  memset(sp,0,sizeof(sp));
  memset(dp,-1,sizeof(dp));
  cin>>w>>h;
  string st[h];
  for(int i=0;i<h;i++) cin>>st[i];
  int sy,sx,gy,gx,n=0;
  map<P,int> m;
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      sp[i][j]=max(sp[i][j],1);
      if(st[i][j]=='M') m[P(i,j)]=n++;
      if(st[i][j]=='S') sy=i,sx=j;
      if(st[i][j]=='G') gy=i,gx=j;
      if(st[i][j]=='#'){
	for(int k=1;k<=3;k++){
	  for(int a=-(4-k);a<=4-k;a++){
	    if(in(i-(4-k),j+a)) sp[i-(4-k)][j+a]=max(sp[i-(4-k)][j+a],k);
	    if(in(i+(4-k),j+a)) sp[i+(4-k)][j+a]=max(sp[i+(4-k)][j+a],k);
	    if(in(i+a,j-(4-k))) sp[i+a][j-(4-k)]=max(sp[i+a][j-(4-k)],k);
	    if(in(i+a,j+(4-k))) sp[i+a][j+(4-k)]=max(sp[i+a][j+(4-k)],k);
	  }
	}
      }
    }
  }
  /*//
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      cout<<sp[i][j];
    }
    cout<<endl;
  }
  //*/
  priority_queue<sta> q;
  q.push(sta(sy,sx,0,0));
  dp[sy][sx][0]=0;
  int ax[]={1,-1,0,0};
  int ay[]={0,0,1,-1};
  while(!q.empty()){
    sta s=q.top();q.pop();
    if(dp[s.y][s.x][s.b]<s.d) continue;
    //cout<<s.y<<" "<<s.x<<" "<<s.b<<" "<<s.d<<endl;
    for(int k=0;k<4;k++){
      int ny=s.y+ay[k],nx=s.x+ax[k],nb=s.b,nd=s.d+sp[s.y][s.x];
      if(!in(ny,nx)) continue;
      if(st[ny][nx]=='#') continue;
      if(m.count(P(ny,nx))) nb|=1<<m[P(ny,nx)];
      if(dp[ny][nx][nb]<0||dp[ny][nx][nb]>nd){
	dp[ny][nx][nb]=nd;
	q.push(sta(ny,nx,nb,nd));
      }
    }
  }
  cout<<dp[gy][gx][(1<<n)-1]<<endl;
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4900
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef pair<P,P> PP;
int dx[4]={-1,0,1,0},dy[4]={0,-1,0,1};
bool check(int n,int m,int x,int y) {return x>=0&&x<n&&y>=0&&y<m;}

int a[111][111],d[1<<5][111][111];
map<P,int> ma;
int main() {
  int n,m;
  cin >> m >> n;
  string s[n];
  for(int i=0; i<n; i++) cin >> s[i];
  priority_queue<PP,vector<PP>,greater<PP> > que;
  for(int i=0; i<n; i++) {
    for(int j=0; j<m; j++) {
      a[i][j]=1;
      for(int k=0; k<(1<<5); k++) d[k][i][j]=1<<29;
      if(s[i][j]=='S') {
        d[0][i][j]=0;
        que.push(PP(P(0,0),P(i,j)));
      }
      if(s[i][j]=='M') {
        int k=ma.size();
        ma[P(i,j)]=k;
      }
      for(int k=-2; k<=2; k++) {
        for(int l=-2; l<=2; l++) {
          int x=i+k,y=j+l;
          if(!check(n,m,x,y)||s[x][y]!='#') continue;
          int d=max(abs(i-x),abs(j-y));
          if(d==1) a[i][j]=max(a[i][j],3);
          if(d==2) a[i][j]=max(a[i][j],2);
        }
      }
    }
  }
  while(!que.empty()) {
    PP p=que.top();que.pop();
    int xx=p.second.first,yy=p.second.second,cc=p.first.first,tt=p.first.second;
    if(s[xx][yy]=='G'&&tt==(1<<ma.size())-1) {
      cout << d[tt][xx][yy] << endl;
      return 0;
    }
    if(d[tt][xx][yy]<cc) continue;
    for(int i=0; i<4; i++) {
      int x=xx+dx[i],y=yy+dy[i];
      int t=tt;
      if(!check(n,m,x,y)||s[x][y]=='#') continue;
      if(s[x][y]=='M') t|=1<<ma[P(x,y)];
      if(d[t][x][y]<=d[tt][xx][yy]+a[xx][yy]) continue;
      d[t][x][y]=d[tt][xx][yy]+a[xx][yy];
      que.push(PP(P(d[t][x][y],t),P(x,y)));
    }
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 4756
final_rank: 9