There are n cities connected by m flights. Each fight starts from city u and arrives at v with a price w.Now given all the cities and flights, together with starting city src and the destination dst, your task is to find the cheapest price from src to dst with up to k stops. If there is no such route, output -1.app
本題給定起始點和重點,還給定各個點之間的鏈接,一看就知道是要搜索。另外因爲給定了最大深度K,使用廣度優先搜索會比較方便,由於每一層的深度都是同樣的,不用像DFS那樣來回修改深度值。這題OJ的難點在於如何剪枝來知足對時間和空間的優化,對於某一個航線,在什麼樣的狀況下能夠確認不用再往下尋找了呢?天然地想到用一個visited的map來記錄哪些訪問過,但是即便訪問過,也不能徹底說明不用繼續尋找了,由於可能某種方案雖然中轉多後面才遇到,可是總價卻少。因此對於每一個訪問過的節點,咱們要記錄當前最低的總價,只有當到達該地新的總價更低時,才繼續尋找,若是該方案到達該地的總價已經高於以前的方案的話,就沒有必要繼續尋找了,從該地到終點的最優線路反正都是同樣的。優化
Goui
func buildGraph(flights [][]int) map[int]map[int]int { graph := map[int]map[int]int{} for _, flight := range flights { src, dst, cost := flight[0], flight[1], flight[2] cmap, ok := graph[src] if !ok { cmap = map[int]int{} } // cmap is a map from destination to cost cmap[dst] = cost graph[src] = cmap } return graph } func findCheapestPrice(n int, flights [][]int, src int, dst int, K int) int { // build the graph given edges first graph := buildGraph(flights) queue := [][]int{{src, 0}} stops := -1 cheapest := math.MaxInt64 visited := map[int]int{} // BFS for len(queue) > 0 && stops <= K { size := len(queue) for i := 0; i < size; i++ { curr := queue[i] from, sum := curr[0], curr[1] if from == dst && sum < cheapest { cheapest = sum continue } toMap := graph[from] for to, cost := range toMap { // if the total cost is higher than before, there's no need to keep looking if min, ok := visited[to]; ok && sum+cost > min { continue } queue = append(queue, []int{to, sum + cost}) visited[to] = sum + cost } } queue = queue[size:len(queue)] stops++ } if cheapest == math.MaxInt64 { return -1 } return cheapest }