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<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;

int n,m,l,cnt,mx,my;
char a[1009][1009];
int vis[1009][1009];
pair<int,int> p[10],st;
int mov[4][2] = {1,0,0,-1,-1,0,0,1};
struct status
{
    int x,y;
    int ord;
    status(int a,int b,int c)
    {
        x = a, y = b, ord = c;
    }
};

void bfs(int x,int y,int color)
{
    queue <struct status> q;
    struct status temp(x,y,0);
    q.push(temp);
    int flag = 0;
    while(!q.empty())
    {
        struct status nw = q.front();
        q.pop();
        if(nw.x == p[color].first && nw.y == p[color].second)
        {
            cnt += nw.ord;
            break;
        }
        vis[nw.x][nw.y] = 1;
        for(int i=0;i<4;i++)
        {
            int tx = mov[i][0] + nw.x, ty = nw.y + mov[i][1];
            if(tx>=0 && tx< n && ty>=0 && ty< m && !vis[tx][ty] && a[tx][ty] != 'X')
            {
                struct status tmp(tx,ty,nw.ord+1);
                q.push(tmp);
                vis[tx][ty] = 1;
            }
        }
    }
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&l))
    {
        getchar();
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%c",&a[i][j]);
                if(a[i][j]>='0' && a[i][j]<='9')
                    p[a[i][j]-'0'].first = i, p[a[i][j]-'0'].second = j;
                if(a[i][j] == 'S') st.first = i, st.second = j;
            }
            getchar();
        }

        int sx = st.first, sy = st.second;
        cnt = 0;
        for(int i=1;i<=l;i++)
        {
            memset(vis,0,sizeof(vis));
            bfs(sx,sy,i);
            sx = p[i].first, sy = p[i].second;
        }
        printf("%d\n",cnt);
    }
    return 0;
}

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;

struct node {int d; point p;};

int walk(point s, point e, map m) {
	queue<node> q;
	static point d[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

	q.push({0, s});

	while (!q.empty()) {
		node n = q.front();
		q.pop();
		if (n.p.x == e.x && n.p.y == e.y)
			return n.d;
		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 = 'X';
					q.push({n.d + 1, p});
				}
			}
		}
	}
	return 0;
}

int main() {
	int h = in(), w = in(), d = 0;
	map m(h);
	vector<point> p(in());
	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 <iostream>
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <math.h>
#include <utility>
#include <string>
#include <ctype.h>
#include <cstring>
#include <cstdio>
#include <sstream>
#include <functional>

using namespace std;

#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define INF 114514810
#define ll long long
//#define scanf scanf_s

char city[1005][1005];
int way[1005][1005];
int di[4] = { -1, 0, 0, 1 }; int dj[4] = { 0, -1, 1, 0 };

int main()
{
	int h, w, n;
	cin >> h >> w >> n;
	REP(i, h)REP(j, w) cin >> city[i][j];
	typedef queue<pair<int, int>> que;
	que start;
	REP(i, h)REP(j, w)
	{
		if (city[i][j] == 'S') start.push(make_pair(i, j));
	}
	FOR(k, 1, n+1)
	{
		REP(i, h)REP(j, w)
		{
			if (city[i][j] - '0' == k)
			{
				start.push(make_pair(i, j));
			}
		}
	}
	int cnt = 0;

	REP(i,n)
	{
		REP(i, 1005)REP(j, 1005) way[i][j] = INF;
		que q; 
		way[start.front().first][start.front().second] = 0;
		q.push(start.front());
		start.pop();
		while (1)
		{
			int tmpi = q.front().first; int tmpj = q.front().second;
			q.pop();
			if (tmpi == start.front().first&&tmpj == start.front().second)
			{
				cnt += way[tmpi][tmpj];
				break;
			}
			else
			{
				REP(i, 4)
				{
					if (tmpi + di[i] >= 0 && tmpi + di[i] < h &&tmpj + dj[i] >= 0 && tmpj + dj[i] < w && city[tmpi + di[i]][tmpj + dj[i]] != 'X' && way[tmpi + di[i]][tmpj + dj[i]] == INF)
					{
						way[tmpi + di[i]][tmpj + dj[i]] = way[tmpi][tmpj] + 1;
						q.push(make_pair(tmpi + di[i], tmpj + dj[i]));
					}
				}
			}
		}
	}
	cout << cnt << endl;

	return 0;
}