import heapq
def wf( mp):
h, w = len(mp), len(mp[0])
for i in range(h*w):
if mp[i//w][i%w]=='S': str =i
if mp[i//w][i%w]=='G': gol =i
a = [[999999] * (h*w) for _ in range(h*w)]
for i in range(h*w): a[i][i] = 0
for i in range(h):
for j in range(w):
ch = mp[i][j]
dst = 0 if ch=='S' or ch=='G' else int(ch)
if i>0: a[(i-1)*w+j][i*w+j] = dst
if j>0: a[i*w+(j-1)][i*w+j] = dst
if i<h-1:a[(i+1)*w+j][i*w+j] =dst
if j<w-1: a[i*w+j+1][i*w+j] = dst
for k in range(h*w):
for i in range(h*w):
for j in range(h*w):
a[i][j] = min(a[i][j], a[i][k] + a[k][j])
#print(a)
print("\t\t(wf-ans=%d)" %a[str][gol])
### spfa 単一始点最短路
import collections # g = [[] for _ in range(n)]
inf = 10**14
def spfa(mp):
h, w = len(mp), len(mp[0])
for i in range(h*w):
if mp[i//w][i%w]=='S': sy, sx = i//w, i%w
if mp[i//w][i%w]=='G': gy, gx = i//w, i%w
dr = [0, 1, 0, -1, 0]
qu = []
inQ = [[False] * w for _ in range(h)]
ds = [[999999] * w for _ in range(h)]
ds[sy][sx] = 0
qu = collections.deque()
qu.append(sy*w+sx)
while qu:
cr = qu.popleft()
cy, cx = cr//w, cr%w
inQ[cy][cx] = False
for j in range(4):
ny, nx = cy + dr[j], cx + dr[j+1]
if ny<0 or ny>=h or nx<0 or nx>=w: continue
nd = mp[ny][nx]
if nd =='G' or nd=='S': nd = '0'
if ds[ny][nx] <= ds[cy][cx] + int(nd): continue
ds[ny][nx] = ds[cy][cx] + int(nd)
if inQ[ny][nx]: continue
qu.append(ny*w+nx)
inQ[ny][nx] = True
return ds[gy][gx]
###
def dujkstra( mp):
h, w = len(mp), len(mp[0])
for i in range(h*w):
if mp[i//w][i%w]=='S': sy, sx = i//w, i%w
if mp[i//w][i%w]=='G': gy, gx = i//w, i%w
dr = [0, 1, 0, -1]
qa = []
pre = [[-1] * w for _ in range(h)]
ds = [[11*h*w] * w for _ in range(h)]
ds[sy][sx] = 0
heapq.heappush(qa, [0, sy, sx])
while len(qa) >0:
cd, cy,cx = heapq.heappop(qa)
if ds[cy][cx] < cd: continue
for i in range(4):
ny = cy+dr[i]; nx = cx+dr[i^1]
if ny<0 or ny>=h or nx<0 or nx>=w: continue
nd = mp[ny][nx]
if nd =='G' or nd=='S': nd = '0'
if ds[cy][cx] + int(nd) < ds[ny][nx]:
ds[ny][nx] = ds[cy][cx] + int(nd)
heapq.heappush(qa, [ds[ny][nx], ny, nx])
pre[ny][nx] = cy*w+cx
# 以下 経路表示
dmp=[['.'] * w for _ in range(h)]
dmp[sy][sx] ='S'; dmp[gy][gx] ='G'
cy, cx = gy, gx
while True:
su = pre[cy][cx]
cy, cx = su//w, su%w
if mp[cy][cx] == 'S': break
dmp[cy][cx] = mp[cy][cx]
for i,a in enumerate(dmp):
if w<45 : print("%s %s"%(''.join(a), mp[i]))
else : print("%s " %(''.join(a)))
return ds[gy][gx]
hdoc = """
S5111
1115G
S1111
98642
G1111
13457689768914512071934123457
G4578901258901212890361125312
37890423076834712378998725463
16890102569615902061456259893
34582934765923812893461515232
57896123896741378915691551697
89013897456123457162501835479
21389046013845610034623405686
8902346203948612341356362342S
"""
nmp=[]
for ln in hdoc.split('\n'):
if len(ln) < 4 and len(nmp) > 0:
#for s in nmp: print(s)
print(" ===> %d" %dujkstra(nmp))
wf(nmp)
print("\t\t(spfa-ans=%d)\n" %spfa(nmp))
nmp = []
if len(ln) >3: nmp.append(ln)
aW1wb3J0IGhlYXBxCgpkZWYgd2YoIG1wKToKICBoLCB3ID0gbGVuKG1wKSwgbGVuKG1wWzBdKQogIGZvciBpIGluIHJhbmdlKGgqdyk6CiAgICBpZiBtcFtpLy93XVtpJXddPT0nUyc6IHN0ciA9aQogICAgaWYgbXBbaS8vd11baSV3XT09J0cnOiBnb2wgPWkKICBhID0gW1s5OTk5OTldICogKGgqdykgZm9yIF8gaW4gcmFuZ2UoaCp3KV0KICBmb3IgaSBpbiByYW5nZShoKncpOiBhW2ldW2ldID0gMAogIGZvciBpIGluIHJhbmdlKGgpOgogICAgZm9yIGogaW4gcmFuZ2Uodyk6CiAgICAgIGNoID0gbXBbaV1bal0KICAgICAgZHN0ID0gMCBpZiBjaD09J1MnIG9yIGNoPT0nRycgZWxzZSBpbnQoY2gpCiAgICAgIGlmIGk+MDogYVsoaS0xKSp3K2pdW2kqdytqXSA9IGRzdAogICAgICBpZiBqPjA6IGFbaSp3KyhqLTEpXVtpKncral0gPSBkc3QKICAgICAgaWYgaTxoLTE6YVsoaSsxKSp3K2pdW2kqdytqXSA9ZHN0CiAgICAgIGlmIGo8dy0xOiBhW2kqdytqKzFdW2kqdytqXSA9IGRzdAogIGZvciBrIGluIHJhbmdlKGgqdyk6CiAgICBmb3IgaSBpbiByYW5nZShoKncpOgogICAgICBmb3IgaiBpbiByYW5nZShoKncpOgogICAgICAgICAgYVtpXVtqXSA9IG1pbihhW2ldW2pdLCBhW2ldW2tdICsgYVtrXVtqXSkKICAjcHJpbnQoYSkKICBwcmludCgiXHRcdCh3Zi1hbnM9JWQpIiAlYVtzdHJdW2dvbF0pCgojIyMgc3BmYSDljZjkuIDlp4vngrnmnIDnn63ot68KaW1wb3J0IGNvbGxlY3Rpb25zICMgZyA9IFtbXSBmb3IgXyBpbiByYW5nZShuKV0KaW5mID0gMTAqKjE0CmRlZiBzcGZhKG1wKToKICBoLCB3ID0gbGVuKG1wKSwgbGVuKG1wWzBdKQogIGZvciBpIGluIHJhbmdlKGgqdyk6CiAgICBpZiBtcFtpLy93XVtpJXddPT0nUyc6IHN5LCBzeCA9IGkvL3csIGkldwogICAgaWYgbXBbaS8vd11baSV3XT09J0cnOiBneSwgZ3ggPSBpLy93LCBpJXcKICBkciA9IFswLCAxLCAwLCAtMSwgMF0KICBxdSA9IFtdCiAgaW5RID0gW1tGYWxzZV0gKiB3IGZvciBfIGluIHJhbmdlKGgpXQogIGRzID0gW1s5OTk5OTldICogdyBmb3IgXyBpbiByYW5nZShoKV0KICBkc1tzeV1bc3hdID0gMAogIAogIAogIHF1ID0gY29sbGVjdGlvbnMuZGVxdWUoKQogIHF1LmFwcGVuZChzeSp3K3N4KQogIHdoaWxlIHF1OgogICAgY3IgPSBxdS5wb3BsZWZ0KCkKICAgIGN5LCBjeCA9IGNyLy93LCBjciV3CiAgICBpblFbY3ldW2N4XSA9IEZhbHNlCiAgICAKICAgIGZvciBqIGluIHJhbmdlKDQpOgogICAgICBueSwgbnggPSBjeSArIGRyW2pdLCBjeCArIGRyW2orMV0KICAgICAgaWYgbnk8MCBvciBueT49aCBvciBueDwwIG9yIG54Pj13OiBjb250aW51ZQogICAgICBuZCA9IG1wW255XVtueF0KICAgICAgaWYgbmQgPT0nRycgb3IgbmQ9PSdTJzogbmQgPSAnMCcKICAgICAgaWYgZHNbbnldW254XSA8PSBkc1tjeV1bY3hdICsgaW50KG5kKTogY29udGludWUKICAgICAgZHNbbnldW254XSA9IGRzW2N5XVtjeF0gKyBpbnQobmQpCiAgICAgIGlmIGluUVtueV1bbnhdOiBjb250aW51ZQogICAgICBxdS5hcHBlbmQobnkqdytueCkKICAgICAgaW5RW255XVtueF0gPSBUcnVlCiAgcmV0dXJuIGRzW2d5XVtneF0KICAjIyMgCgoKZGVmIGR1amtzdHJhKCBtcCk6CiAgaCwgdyA9IGxlbihtcCksIGxlbihtcFswXSkKICBmb3IgaSBpbiByYW5nZShoKncpOgogICAgaWYgbXBbaS8vd11baSV3XT09J1MnOiBzeSwgc3ggPSBpLy93LCBpJXcKICAgIGlmIG1wW2kvL3ddW2kld109PSdHJzogZ3ksIGd4ID0gaS8vdywgaSV3CiAgZHIgPSBbMCwgMSwgMCwgLTFdCiAgcWEgPSBbXQogIHByZSA9IFtbLTFdICogdyBmb3IgXyBpbiByYW5nZShoKV0KICBkcyA9IFtbMTEqaCp3XSAqIHcgZm9yIF8gaW4gcmFuZ2UoaCldCiAgZHNbc3ldW3N4XSA9IDAKICBoZWFwcS5oZWFwcHVzaChxYSwgWzAsIHN5LCBzeF0pCiAgd2hpbGUgbGVuKHFhKSA+MDoKICAgIGNkLCBjeSxjeCA9IGhlYXBxLmhlYXBwb3AocWEpCiAgICBpZiBkc1tjeV1bY3hdIDwgY2Q6IGNvbnRpbnVlCiAgICBmb3IgaSBpbiByYW5nZSg0KToKICAgICAgbnkgPSBjeStkcltpXTsgbnggPSBjeCtkcltpXjFdCiAgICAgIGlmIG55PDAgb3Igbnk+PWggb3Igbng8MCBvciBueD49dzogY29udGludWUKICAgICAgbmQgPSBtcFtueV1bbnhdCiAgICAgIGlmIG5kID09J0cnIG9yIG5kPT0nUyc6IG5kID0gJzAnCiAgICAgIGlmIGRzW2N5XVtjeF0gKyBpbnQobmQpIDwgZHNbbnldW254XToKICAgICAgICBkc1tueV1bbnhdID0gZHNbY3ldW2N4XSArIGludChuZCkKICAgICAgICBoZWFwcS5oZWFwcHVzaChxYSwgW2RzW255XVtueF0sIG55LCBueF0pCiAgICAgICAgcHJlW255XVtueF0gPSBjeSp3K2N4CgojIOS7peS4iyDntYzot6/ooajnpLoKICBkbXA9W1snLiddICogdyBmb3IgXyBpbiByYW5nZShoKV0KICBkbXBbc3ldW3N4XSA9J1MnOyBkbXBbZ3ldW2d4XSA9J0cnCiAgY3ksIGN4ID0gZ3ksIGd4CiAgd2hpbGUgVHJ1ZToKICAgIHN1ID0gcHJlW2N5XVtjeF0KICAgIGN5LCBjeCA9IHN1Ly93LCBzdSV3CiAgICBpZiBtcFtjeV1bY3hdID09ICdTJzogYnJlYWsKICAgIGRtcFtjeV1bY3hdID0gbXBbY3ldW2N4XQogIGZvciBpLGEgaW4gIGVudW1lcmF0ZShkbXApOgogICAgaWYgdzw0NSA6IHByaW50KCIlcyAgICVzIiUoJycuam9pbihhKSwgbXBbaV0pKQogICAgZWxzZSA6IHByaW50KCIlcyAiICUoJycuam9pbihhKSkpCiAgcmV0dXJuICBkc1tneV1bZ3hdCgoKCmhkb2MgPSAiIiIKUzUxMTEKMTExNUcKClMxMTExCjk4NjQyCkcxMTExCgoxMzQ1NzY4OTc2ODkxNDUxMjA3MTkzNDEyMzQ1NwpHNDU3ODkwMTI1ODkwMTIxMjg5MDM2MTEyNTMxMgozNzg5MDQyMzA3NjgzNDcxMjM3ODk5ODcyNTQ2MwoxNjg5MDEwMjU2OTYxNTkwMjA2MTQ1NjI1OTg5MwozNDU4MjkzNDc2NTkyMzgxMjg5MzQ2MTUxNTIzMgo1Nzg5NjEyMzg5Njc0MTM3ODkxNTY5MTU1MTY5Nwo4OTAxMzg5NzQ1NjEyMzQ1NzE2MjUwMTgzNTQ3OQoyMTM4OTA0NjAxMzg0NTYxMDAzNDYyMzQwNTY4Ngo4OTAyMzQ2MjAzOTQ4NjEyMzQxMzU2MzYyMzQyUwoKIiIiCgoKbm1wPVtdCmZvciBsbiBpbiBoZG9jLnNwbGl0KCdcbicpOgogIGlmIGxlbihsbikgPCA0IGFuZCBsZW4obm1wKSA+IDA6CiAgICAjZm9yIHMgaW4gbm1wOiBwcmludChzKQogICAgcHJpbnQoIiAgID09PT4gJWQiICVkdWprc3RyYShubXApKQogICAgd2Yobm1wKQogICAgcHJpbnQoIlx0XHQoc3BmYS1hbnM9JWQpXG4iICVzcGZhKG5tcCkpCiAgICBubXAgPSBbXQogIGlmIGxlbihsbikgPjM6IG5tcC5hcHBlbmQobG4pCgo=