バックトラッキングで解いたら

http://okajima.air-nifty.com/b/2010/01/post-abc6.html
Lv3らしい。でしょうね・・30分ぐらい。

高校生で効率良く解いた方がおられた。
http://d.hatena.ne.jp/qnighy/20100111/1263191078

# coding: utf-8
import sys
m = sys.stdin.read().splitlines()

# backtracking
mstep = len(m)*len(m[0])
mpath = None
path = set()
push = lambda x: path.add(x)
pop = lambda x: path.remove(x)
def backtracking(x, y, step):
    global mstep,mpath
    if step >= mstep:
        return
    push((x,y))
    if m[x][y] == "G":
        if step < mstep:
            mstep = step
            mpath = path.copy()
    else:
        for dx,dy in [(-1,0), (0,-1), (+1,0), (0,+1)]:
            nx = x + dx
            ny = y + dy
            if not (0 <= nx < len(m)) or not (0 <= ny < len(m[0])):
                continue
            if m[nx][ny] in " G" and not (nx,ny) in path:
                backtracking(nx, ny, step+1)
    pop((x,y))

sx,sy = None,None
for i in xrange(len(m)):
    for j in xrange(len(m[0])):
        if m[i][j] == "S":
            sx,sy = i,j
            break
backtracking(sx, sy, 0)

for i in xrange(len(m)):
    for j in xrange(len(m[0])):
        if (i,j) in mpath and not m[i][j] in "SG":
            sys.stdout.write("$")
        else:
            sys.stdout.write(m[i][j])
    sys.stdout.write("\n")

追記:
ダイクストラ法によるプログラム。バックトラックとくらべてやっぱりちょっと頭を使う。

# coding: utf-8
import sys

m = sys.stdin.read()

n = map(list, m.splitlines())
w,h = len(n[0]), len(n)

m = m.replace("\n", "")

wh = w*h
dist,prev,fix = [1e100]*wh, [None]*wh, [False]*wh

src = m.index("S")
dst = m.index("G")

def edgesfrom(u):
    edges = []
    if u % w !=    0 and m[u-1] != "*": edges.append((u, u-1))
    if u % w !=  w-1 and m[u+1] != "*": edges.append((u, u+1))
    if u     <  wh-w and m[u+w] != "*": edges.append((u, u+w))
    if u     >=    w and m[u-w] != "*": edges.append((u, u-w))
    return edges

dist[src] = 0
fix[src] = True
bound = set(edgesfrom(src))  # 囲みの境界にあるエッジを記憶する
while len(bound) != 0:
    d,u = min((dist[s]+1, t) for s,t in bound)
    fix[u],dist[u] = True, d
    bound = set(b for b in bound if b[1] != u)
    for u,v in edgesfrom(u):
        if not fix[v]:
            bound.add((u,v))
    for u,v in edgesfrom(u):
        d = dist[u] + 1
        if d < dist[v]:
            dist[v] = d
            prev[v] = u
# 経路を求める
u = prev[dst]
while not u is None:
    n[u/w][u%w] = '$'
    u = prev[u]
print "\n".join(map(lambda line: "".join(line), n))