Language: C++

#include<iostream>
#include<map>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<sstream>
#include<queue>
#include<cassert>
#include<deque>
#include<set>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<29)
#define all(n) (n).begin(),(n).end()
#define MAX 12
#define sinf (30000)
#define cinf (254)

using namespace std;

typedef unsigned short us;
typedef unsigned char uc;

struct Pox
{
  vector<uc> array;
  us cost;
  us prev;
  Pox(vector<uc> array=vector<uc>(),us cost=sinf,us prev=sinf):array(array),cost(cost),prev(prev){}
};

uc dx[] = {1,0,-1,0};
uc dy[] = {0,-1,0,1};
us max_ans;
//int dx[] = {0,1,0,-1};
//int dy[] = {1,0,-1,0};
uc ev[MAX*MAX][MAX*MAX];//評価値 ev[a][b] := aからbまでの最短コスト
char g[MAX][MAX];
us st[2],h,w,ice_number;
int ice[MAX*MAX];
int ice_cnt[MAX*MAX];
set<vector<uc> > mincost;
//set<ull> mincost;
//priority_queue<Pox> Q;
//queue<Pox> Q;
deque<Pox> Q;



void init()
{
  max_ans = 0;
  // while(!Q.empty())Q.pop_back();
  ice_number = 0;
  rep(i,h)rep(j,w)ice[j+i*w] = ice_cnt[j+i*w] = inf;
  //rep(i,h*w)rep(j,h*w)ev[i][j] = inf;
  mincost.clear();
}

void getInput()
{
  rep(i,h)
    {
      getchar();
      rep(j,w)
	{
	  scanf("%c",&g[i][j]);
	  if(g[i][j] == 'S')
	    {
	      st[0] = j + i * w;
	      g[i][j] = '.';
	    }
	  if(g[i][j] == 'G')
	    {
	      st[1] = j + i * w;
	      g[i][j] = '.';
	    }
	  if(g[i][j] == '.')max_ans++;
	}
    }
}

void make_ev()
{
  rep(sp,h*w)
    {
      ev[sp][sp] = 0;
      deque<us> deq;
      deq.push_back(sp);

      while(!deq.empty())
	{
	  int cur = deq.front(); deq.pop_front();
	  if(cur == st[1])break;
	  rep(i,4)
	    {
	      uc nx = cur % w + dx[i];
	      uc ny = cur / w + dy[i];
	      if(!(0 <= nx && nx < w && 0 <= ny && ny < h))continue;
	      if(g[ny][nx] == '#')continue;
	      if(ev[sp][nx+ny*w] > ev[sp][cur]+1)
		{
		  ev[sp][nx+ny*w] = ev[sp][cur]+1;
		  deq.push_back(nx+ny*w);
		}
	    }
	}
    }
}

void draw(uc cur,uc id,int &cnt)
{
  if(ice[cur] != inf)return;
  ice[cur] = id;
  cnt++;
  rep(i,4)
    {
      uc nx = cur % w + dx[i];
      uc ny = cur / w + dy[i];
      if(!(0 <= nx && nx < w && 0 <= ny && ny < h))continue;
      if(g[ny][nx] != 'X')continue;
      draw(nx+ny*w,id,cnt);
    }
}

bool compute(us depth)
{

  while(!Q.empty())
    {
      Pox pox = Q.front(); Q.pop_front();

      //cnt++;
      //if(pox.cost + ev[pox.array[ice_number]][st[1]] >= max_ans)continue;
      //if(cnt > 10 && !Q.empty() && (cnt%60 == 0 || cnt %120 == 0 || cnt % 73 == 0))Q.pop();
      // int cost = pox.cost + ev[pox.array[ice_number]][st[1]];
      //if(cost >= ev[st[0]][st[1]]*5)continue;
      /*
      if( (cnt % 666 == 0|| cnt % 700 == 0) && !Q.empty())
	{
	  Pox pre = pox;
	  pox = Q.front(); Q.pop_front();
	  continue;
	  //Q.push(pre);
	}
      */
      /*
      if(cnt >= 100 && cnt % 3 == 0 && Q.size() >= 2)
	{
	  Pox store = pox;
	  Pox store2 = Q.top(); Q.pop();
	  pox = Q.top(); Q.pop();
	  Q.push(store);
	  Q.push(store2);
	}
      */
      /*
      if(cnt >= 100 && cnt % 7 == 0 && Q.size() >= 5)
	{
	  Pox store[3];
	  store[0] = pox;
	  rep(i,2)
	    {
	      store[i+1] = Q.top(); Q.pop();
	    }
	  pox = Q.top(); Q.pop();
	  rep(i,3)Q.push(store[i]);
	}
      */
      /*
      cout << "pox:array:\n";
      rep(i,pox.array.size())
	cout << "array[" << i << "] = " << pox.array[i] << endl;
      cout << "pox:cost:" << pox.cost << endl << endl;
      */
      if(st[1] == pox.array[ice_number])
	{
	  //printf("h\n",pox.cost);
	  cout << pox.cost << endl;
	  return true;
	}

      if(pox.cost + ev[pox.array[ice_number]][st[1]] >= max_ans)
	{
	  continue;
	}

      if(pox.cost + ev[pox.array[ice_number]][st[1]] >= depth)
	{
	  Q.push_back(pox);
	  return false;
	}


      rep(i,4)
	{
	  if(pox.prev != -1 && pox.prev == (i+2)%4)continue;
	  uc nx = pox.array[ice_number] % w + dx[i];
	  uc ny = pox.array[ice_number] / w + dy[i];
	  if(!(0 <= nx && nx < w && 0 <= ny && ny < h))continue;
	  if(g[ny][nx] == '#')continue;

	  vector<uc> next = pox.array;	
	  next[ice_number] = nx+ny*w;  

	  if(g[ny][nx] == 'X')
	    {
	      if(ice_cnt[ice[nx+ny*w]] < 2*(pox.array[ice[nx+ny*w]] + 1))continue;

	      next[ice[nx+ny*w]]++;
	    }


	  if(mincost.find(next) == mincost.end())
	    {
	      mincost.insert(next);
	      if(Q.front().cost > pox.cost+1)
		Q.push_front(Pox(next,pox.cost+1,i));
	      else
		Q.push_back(Pox(next,pox.cost+1,i));
	    }
	}
    }
  return false;
}

int main()
{
  //while(scanf("h h",&w,&h),w|h)
  while(cin >> w >> h,w|h)
    {
      init();
      getInput();
      make_ev();

      rep(y,h)rep(x,w)
	if(g[y][x] == 'X' && ice[x+y*w] == inf)
	    {
	      int cnt = 0;
	      draw(x+y*w,ice_number,cnt);
	      ice_cnt[ice_number] = cnt;
	      ice_number++;      
	    }

      rep(i,ice_number)max_ans += ice_cnt[i];

      vector<uc> initial_array(ice_number+1,0);
      initial_array[ice_number] = st[0];
      Q.push_back(Pox(initial_array,0,-1));
      mincost.insert(initial_array);
      us depth = 0;
      while(!compute(depth++));	
      while(!Q.empty())Q.pop_back();
    }
  return 0;
}

Compiler output:
a.cc:33:16: error: narrowing conversion of '-1' from 'int' to 'uc' {aka 'unsigned char'} [-Wnarrowing]
   33 | uc dx[] = {1,0,-1,0};
      |                ^~
a.cc:34:14: error: narrowing conversion of '-1' from 'int' to 'uc' {aka 'unsigned char'} [-Wnarrowing]
   34 | uc dy[] = {0,-1,0,1};
      |              ^~