Buggy python submission (verdict: Runtime Error):
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)

def search(field,distance,ch,cv,eh,ev,step):
	if not (0<=ch<len(field)):		return
	if not (0<=cv<len(field[ch])):	return
	if field[ch][cv]=='X':			return
	if distance[ch][cv]<step: 		return

	distance[ch][cv] = step
	search(field,distance,ch+1,cv,eh,ev,step+1)
	search(field,distance,ch-1,cv,eh,ev,step+1)
	search(field,distance,ch,cv+1,eh,ev,step+1)
	search(field,distance,ch,cv-1,eh,ev,step+1)

def calculate_distance(field,locations,current_HP):
	ch,cv=locations[current_HP-1]
	eh,ev=locations[current_HP]
	distance=[[10**6 for _ in range(len(field[0]))] for __ in range(len(field))]
	search(field,distance,ch,cv,eh,ev,0)
#	print('='*50)
#	for v in distance:
#		print(v)
#	print('-'*50)
	return distance[eh][ev]
#	return 0

def solve(field,locations):
	total_step=0
	for current_HP in range(1,len(locations)):
		total_step += calculate_distance(field,locations,current_HP)
	return total_step

def main():
	line=input().strip()
	H,W,N=list(map(int,line.split(' ')))
	field,locations=list(),dict()
	for i in range(H):
		field.append(list(input().strip()))
		for j,x in enumerate(field[-1]):
			if x=='S':
				locations[0] = (i,j,)
			if x.isdigit():
				x = int(x)
				field[-1][j] = x
				locations[x] = (i,j,)
	print(solve(field,locations))

if __name__=='__main__':
	main()

Fixed submission:
# -*- coding: utf-8 -*-

def get_shortest_distance(field,locations,current_HP):
	is_visit = [[False for _ in range(len(field[0]))] for __ in range(len(field))]
	frontier = list([locations[current_HP-1]])
	for step in range(len(field)*len(field[0])):
		next_frontier = set()
		for cx,cy in frontier:
			for dx,dy in [[0,1],[0,-1],[1,0],[-1,0]]:
				nx, ny = cx+dx, cy+dy
				if (nx,ny)==locations[current_HP]: return step+1
				if not (0<=nx<len(field)):		continue
				if not (0<=ny<len(field[nx])):	continue
				if field[nx][ny]=='X':			continue
				if is_visit[nx][ny]: 			continue
				next_frontier.add((nx,ny))
				is_visit[nx][ny] = True
		frontier = next_frontier

def solve(field,locations):
	total_step=0
	for current_HP in range(1,len(locations)):
		total_step += get_shortest_distance(field,locations,current_HP)
	return total_step

def main():
	line=input().strip()
	H,W,N=list(map(int,line.split(' ')))
	field,locations=list(),dict()
	for i in range(H):
		field.append(list(input().strip()))
		for j,x in enumerate(field[-1]):
			if x=='S':
				locations[0] = (i,j,)
			if x.isdigit():
				x = int(x)
				field[-1][j] = x
				locations[x] = (i,j,)
	print(solve(field,locations))

if __name__=='__main__':
	main()

Buggy python submission (verdict: Runtime Error):
# -*- coding: utf-8 -*-

def get_shortest_distance(field,locations,current_HP):
	is_visit = [[False for _ in range(len(field[0]))] for __ in range(len(field))]
	frontier = set()
	frontier.add(locations[current_HP-1])
	for step in xrange(10**10):
		for cx,cy in frontier:
			if (cx,cy)==locations[current_HP]: return step
			is_visit[cx][cy]=True
		next_frontier = set()
		for cx,cy in list(frontier):
			for dx,dy in [[0,1],[0,-1],[1,0],[-1,0]]:
				nx = cx+dx
				ny = cy+dy
				if not (0<=nx<len(field)):		continue
				if not (0<=ny<len(field[nx])):	continue
				if field[nx][ny]=='X':			continue
				if is_visit[nx][ny]: 			continue
				next_frontier.add((nx,ny))
#		assert len(next_frontier)!=0,(current_HP,is_visit,frontier)
		frontier = next_frontier
#	assert True,('the goal is not reachable')

def solve(field,locations):
	total_step=0
	for current_HP in range(1,len(locations)):
		total_step += get_shortest_distance(field,locations,current_HP)
	return total_step

def main():
	line=input().strip()
	H,W,N=list(map(int,line.split(' ')))
	field,locations=list(),dict()
	for i in range(H):
		field.append(list(input().strip()))
		for j,x in enumerate(field[-1]):
			if x=='S':
				locations[0] = (i,j,)
			if x.isdigit():
				x = int(x)
				field[-1][j] = x
				locations[x] = (i,j,)
	print(solve(field,locations))

if __name__=='__main__':
	main()

Fixed submission:
# -*- coding: utf-8 -*-

def get_shortest_distance(field,locations,current_HP):
	is_visit = [[False for _ in range(len(field[0]))] for __ in range(len(field))]
	frontier = list([locations[current_HP-1]])
	for step in range(len(field)*len(field[0])):
		next_frontier = set()
		for cx,cy in frontier:
			for dx,dy in [[0,1],[0,-1],[1,0],[-1,0]]:
				nx, ny = cx+dx, cy+dy
				if (nx,ny)==locations[current_HP]: return step+1
				if not (0<=nx<len(field)):		continue
				if not (0<=ny<len(field[nx])):	continue
				if field[nx][ny]=='X':			continue
				if is_visit[nx][ny]: 			continue
				next_frontier.add((nx,ny))
				is_visit[nx][ny] = True
		frontier = next_frontier

def solve(field,locations):
	total_step=0
	for current_HP in range(1,len(locations)):
		total_step += get_shortest_distance(field,locations,current_HP)
	return total_step

def main():
	line=input().strip()
	H,W,N=list(map(int,line.split(' ')))
	field,locations=list(),dict()
	for i in range(H):
		field.append(list(input().strip()))
		for j,x in enumerate(field[-1]):
			if x=='S':
				locations[0] = (i,j,)
			if x.isdigit():
				x = int(x)
				field[-1][j] = x
				locations[x] = (i,j,)
	print(solve(field,locations))

if __name__=='__main__':
	main()