Go: ///
// File:  0558.go
// Author: ymiyamoto
//
// Created on Sun Mar  4 20:58:45 2018
//
package main

import (
	"fmt"
	"strconv"
	"strings"
)

type pos struct {
	x, y int
}

var H, W, N int
var graph [][]string

func wfs(p pos, index int) (int, pos) {
	var q []pos
	dists := make([][]int, H)
	for i := range dists {
		dists[i] = make([]int, W)
	}

	q = append(q, p)
	for len(q) > 0 {
		p := q[0]
		dist := dists[p.x][p.y]
		q = q[1:]

		for _, d := range []pos{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} {
			x := p.x + d.x
			y := p.y + d.y
			if 0 <= x && x < H && 0 <= y && y < W && graph[x][y] != "X" && dists[x][y] == 0 {
				dists[x][y] = dist + 1
				q = append(q, pos{x, y})
			}
		}
	}

	for i := range graph {
		for j := range graph[i] {
			if graph[i][j] == strconv.Itoa(index) {
				return dists[i][j], pos{i, j}
			}
		}
	}

	panic("not found")
}

func main() {
	fmt.Scan(&H, &W, &N)

	var start pos

	graph = make([][]string, H)
	for i := range graph {
		var s string
		fmt.Scan(&s)
		graph[i] = strings.Split(s, "")
		for j := range graph[i] {
			if graph[i][j] == "S" {
				start.x = i
				start.y = j
			}
		}
	}

	count := 0
	for i := 1; i <= N; i++ {
		c, s := wfs(start, i)
		start = s
		count += c
	}

	fmt.Println(count)
}

C++: #include <iostream>
#include <queue>
using namespace std;
int w, h, n;
char map[1024][1024];
int d[1024][1024];
const int direction[4][2] = {
    { -1, 0 },
    { 1, 0 },
    { 0, -1 },
    { 0, 1 },
};
int factory[16][2];
typedef pair<int, int> P;
int bfs(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] = -1;
        }
    }
    queue<P> que;
    que.push(P(sx, sy));
    d[sx][sy] = 0;
    while (que.size())
    {
        const P p = que.front(); que.pop();
        if (p.first == gx && p.second == gy)
        {
            break;
        }
        for (int i = 0; i < 4; ++i)
        {
            int nx = p.first + direction[i][0];
            int ny = p.second + direction[i][1];
            if (0 <= nx && nx < h && 0 <= ny && ny < w && map[nx][ny] != 'X' && d[nx][ny] == -1)
            {
                que.push(P(nx, ny));
                d[nx][ny] = d[p.first][p.second] + 1;
            }
        }
    }

    return d[gx][gy];
}

int main(int argc, char *argv[])
{

    cin >> h >> w >> n;
    for (int i = 0; i < h; ++i)
    {
        for (int j = 0; j < w; ++j)
        {
            cin >> map[i][j];
        }
    }

    for (int i = 0; i < h; ++i)
    {
        for (int j = 0; j < w; ++j)
        {
            if (map[i][j] == 'S')
            {
                factory[0][0] = i;
                factory[0][1] = j;
                map[i][j] = '.';
            }
            else if (isdigit(map[i][j]))
            {
                int index = map[i][j] - '0';
                factory[index][0] = i;
                factory[index][1] = j;
            }
        }
    }

    int step = 0;
    for (int i = 0; i < n; ++i)
    {
        step += bfs(factory[i][0], factory[i][1], factory[i + 1][0], factory[i + 1][1]);
    }

    cout << step << endl;

    return 0;
}
///////////////////////////End Sub//////////////////////////////////

C++: #include <cstdio>
#include <utility>
#include <vector>
#include <string>
#include <queue>
using namespace std;

#define gcu getchar_unlocked
int in(int c){int n=0;bool m=false;if(c=='-')m=true,c=gcu();
	do{n=10*n+(c-'0'),c=gcu();}while(c>='0');return m?-n:n;}
int in() {return in(gcu());}
bool scan(int &n){int c=gcu();return c==EOF?false:(n=in(c),true);}
bool scan(char &c){c=gcu();gcu();return c!=EOF;}
//bool scan(string &s){int c;s="";
//	for(;;){c=gcu();if(c=='\n'||c==' ')return true;else if(c==EOF)return false;s+=c;}}
#define pcu putchar_unlocked
#define vo inline void out
template <typename T>
vo(T n){static char buf[20];char *p=buf;
	if(n<0)pcu('-'),n*=-1;if(!n)*p++='0';else while(n)*p++=n%10+'0',n/=10;
	while (p!=buf)pcu(*--p);}
vo(const char *s){while(*s)pcu(*s++);}
vo(char c){pcu(c);}
vo(string &s){for (char c: s) pcu(c);}
template <typename head, typename... tail> vo(head&& h, tail&&... t){out(h);out(move(t)...);}
//template <typename T> vo(vector<T> &v){for(T &x:v)out(&x == &v[0]?"":" "),out(x);out('\n');}
#undef vo

struct point {int x, y;};
typedef vector<string> map;

int distance(point s, point e) {
	return abs(s.x - e.x) + abs(s.y - e.y);
}

int walk(point s, point e, map m) {
	struct node {
		int g, h, f;
		point p;
		bool operator < (const node &a) const {
			return f > a.f;
		};
	};
	priority_queue<node> q;
	static point d[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

	m[s.y][s.x] = 'O';
	int sd = distance(s, e);
	q.push({0, sd, sd, s});

	while (!q.empty()) {
		node n = q.top();
		q.pop();
		if (!n.h)
			return n.g;
		m[n.p.y][n.p.x] = 'X';
		for (auto p: d) {
			p.x += n.p.x;
			p.y += n.p.y;
			if (p.x >= 0 && p.x < (int) m[0].size()
				&& p.y >= 0 && p.y < (int) m.size()) {
				char &c = m[p.y][p.x];
				if (c == '.') {
					c = 'O';
					int g = n.g + 1, h = distance(p, e);
					q.push({g, h, g + h, p});
				}
			}
		}
	}
	return 0;
}


int main() {
	int h = in(), w = in(), d = 0, n = in();
	vector<string> m(h);
	vector<point> p(n);
	point s;
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			char c = gcu();
			if (isdigit(c)) {
				p[c - '0' - 1] = {j, i};
				c = '.';
			} else if (c == 'S') {
				s = {j, i};
				c = '.';
			}
			m[i].push_back(c);
		}
		gcu();
	}
	for (auto t: p) {
		d += walk(s, t, m);
		s = t;
	}
	out(d, '\n');
}

C++: #include <bits/stdc++.h>
using namespace std;
 
// #define int long long
 
/* short */
#define pb push_back
#define print(x) cout << x << '\n'
 
/* REPmacro */
#define REPS(i, a, n) for (int i = (a); i < (n); i++)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define RREP(i, n) for (int i = 1; i <= (n); i++)
#define DEPS(i, a, n) for (int i = (a); i >= n; i--)
#define DEP(i, n) for (int i = (n); i >= 0; i--)

/* typedef */
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vector<int> > vii;
typedef pair<int, int> pii;

/* const */
const int INF = INT_MAX;
const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

/* func */
inline bool is_uruu(int y) {return (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0));}

int H, W, N;
char field[1024][1024];

int bfs(int sx, int sy, int gx, int gy)
{
  int res[1024][1024];
  memset(res, -1, sizeof(res));
  queue<pii> Q;
  Q.push(pii(sx, sy));
  res[sy][sx] = 0;

  for (; !Q.empty();){
    int x = Q.front().first, y = Q.front().second; Q.pop();
    //cout << "debug: x " << x << " y " << y << endl;
    if (x == gx && y == gy)  break;
    REP(i, 4){
      int mx = x + dx[i], my = y + dy[i];
      if (mx < 0 || my < 0 || mx >= W || my >= H) continue;
      if (field[my][mx] != 'X' && res[my][mx] == -1){
        Q.push(pii(mx, my));
        res[my][mx] = res[y][x] + 1;
      }
    }
  }

  return (res[gy][gx]);
}

signed main()
{
  ios::sync_with_stdio(false);
  pii st;
  pii fac[10];

  cin >> H >> W >> N;
  REP(i, H){
    REP(j, W){
      cin >> field[i][j];
      if (field[i][j] == 'S') st = pii(j, i);
      if (isdigit(field[i][j])) fac[field[i][j] - '0'] = pii(j, i);
    }
  }

  int ans = bfs(st.first, st.second, fac[1].first, fac[1].second);
  REPS(i, 2, N + 1){
    ans += bfs(fac[i - 1].first, fac[i - 1].second, fac[i].first, fac[i].second);
  }
  print(ans);

  return (0);
}