技巧
    bfs
思路
    这里需要分类讨论
    1 不需要KEY也能到达终点
    2 需要KEY时候先算出 D - K 的距离
        2.1 拿到K然后顺路去D
        2.2 拿到K然后返回起点再去D
    3 如果需不需要KEY都能到达时候  取最小值
实现
package main

import (
	"bufio"
	. "fmt"
	"io"
	"math"
	"os"
	"strings"
)

type Pos struct {
	x, y, step int
}

var (
	dx = []int{0, 1, 0, -1}
	dy = []int{1, 0, -1, 0}
)

// 不拿Key
func case1(sx, sy int, maze []string) int {
	vis := [510][510]bool{}
	ans := -1
	q := make([]Pos, 0)
	q = append(q, Pos{sx, sy, 0})
	for len(q) > 0 {
		top := q[0]
		q = q[1:]
		vis[top.x][top.y] = true
		if maze[top.x][top.y] == 'E' {
			ans = top.step
			break
		}
		for i := 0; i < 4; i++ {
			nx, ny := top.x+dx[i], top.y+dy[i]
			if nx >= 0 && ny >= 0 && nx < len(vis) && ny < len(vis[0]) && !vis[nx][ny] && maze[nx][ny] != 'W' && maze[nx][ny] != 'D' {
				q = append(q, Pos{nx, ny, top.step + 1})
			}
		}
	}
	return ans
}

// 拿Key
func case2(sx, sy int, maze []string) int {
	vis := [510][510]bool{}
	ans := -1
	hasKey := false
	var key Pos
	q := make([]Pos, 0)
	q = append(q, Pos{sx, sy, 0})
	for len(q) > 0 {
		top := q[0]
		q = q[1:]
		vis[top.x][top.y] = true
		if maze[top.x][top.y] == 'D' {
			if !hasKey {
				if len(q) == 0 {
					break
				}
				q = append(q, top)
				continue
			} else {
				kdPathQ := make([]Pos, 0)
				kdPathQ = append(kdPathQ, Pos{key.x, key.y, 0})
				visTmp := [510][510]bool{}
				distance := 999999999
				for len(kdPathQ) > 0 {
					tmp := kdPathQ[0]
					kdPathQ = kdPathQ[1:]
					visTmp[tmp.x][tmp.y] = true
					if maze[tmp.x][tmp.y] == 'D' {
						distance = tmp.step
						break
					}
					for i := 0; i < 4; i++ {
						nx, ny := tmp.x+dx[i], tmp.y+dy[i]
						if nx >= 0 && ny >= 0 && nx < len(vis) && ny < len(vis[0]) && maze[nx][ny] != 'W' && !visTmp[nx][ny] {
							kdPathQ = append(kdPathQ, Pos{nx, ny, tmp.step + 1})
						}
					}
				}
				//						先拿到K顺路到D						拿到K返回后再去D
				top.step = int(math.Min(float64(distance+key.step), float64(top.step+2*key.step)))
			}
		} else if maze[top.x][top.y] == 'K' {
			hasKey = true
			key = Pos{top.x, top.y, top.step}
		} else if maze[top.x][top.y] == 'E' {
			ans = top.step
			break
		}

		for i := 0; i < 4; i++ {
			nx, ny := top.x+dx[i], top.y+dy[i]
			if nx >= 0 && ny >= 0 && nx < len(vis) && ny < len(vis[0]) && !vis[nx][ny] && maze[nx][ny] != 'W' {
				q = append(q, Pos{nx, ny, top.step + 1})
			}
		}

	}
	return ans
}

func NC15136(_r io.Reader, _w io.Writer) {
	in, out := bufio.NewReader(_r), bufio.NewWriter(_w)
	defer out.Flush()
	var n, m int
	Fscan(in, &n, &m)
	maze := make([]string, n)
	sx, sy := -1, -1
	for i := 0; i < n; i++ {
		Fscan(in, &maze[i])
		if j := strings.IndexRune(maze[i], 'S'); j != -1 {
			sx, sy = i, j
		}
	}
	if ans := case1(sx, sy, maze); ans != -1 {
		if p := case2(sx, sy, maze); p < ans {
			ans = p
		}
		Fprintln(out, ans)
	} else {
		Fprintln(out, case2(sx, sy, maze))
	}
}
func main() {
	NC15136(os.Stdin, os.Stdout)
}