方法一:深度優先遍歷(回溯算法)
說明:
- 航班沒有重複,且不存在環路;
- 每個航班的價格範圍是
[1, 10000]
。
Java 代碼:
public class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
// 構建鄰接矩陣
int[][] graph = new int[n][n];
for (int[] flight : flights) {
graph[flight[0]][flight[1]] = flight[2];
}
int[] res = new int[1];
res[0] = Integer.MAX_VALUE;
boolean[] visited = new boolean[n];
// 注意:這裏傳 K + 1,K 次經停,總共 K + 1 個站
dfs(graph, src, dst, K + 1, 0, visited, res);
if (res[0] == Integer.MAX_VALUE) {
return -1;
}
return res[0];
}
private void dfs(int[][] graph, int src, int dst, int k, int cost, boolean[] visited, int[] res) {
if (src == dst) {
res[0] = cost;
return;
}
if (k == 0) {
return;
}
int n = graph[src].length;
for (int i = 0; i < n; i++) {
// 注意 1:這裏 graph[src][i] > 0
if (graph[src][i] > 0) {
if (visited[i]) {
continue;
}
if (cost + graph[src][i] > res[0]) {
continue;
}
// 搜索
visited[i] = true;
dfs(graph, i, dst, k - 1, cost + graph[src][i], visited, res);
visited[i] = false;
}
}
}
}
方法二:廣度優先遍歷
Java 代碼:
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
// 構建鄰接矩陣
int[][] graph = new int[n][n];
for (int[] flight : flights) {
graph[flight[0]][flight[1]] = flight[2];
}
int res = Integer.MAX_VALUE;
Queue<int[]> queue = new LinkedList<>();
// [src, 到 src 的花費]
queue.offer(new int[]{src, 0});
int k = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] head = queue.poll();
int currentPrice = head[1];
for (int j = 0; j < n; j++) {
// 注意:這裏 graph[head[0]][j] > 0
if (graph[head[0]][j] > 0) {
if (j == dst) {
res = Math.min(res, currentPrice + graph[head[0]][dst]);
// 注意:這裏不能直接返回,因爲有鬆弛操作
}
if (currentPrice + graph[head[0]][j] < res) {
queue.offer(new int[]{j, currentPrice + graph[head[0]][j]});
}
}
}
}
if (k == K){
break;
}
k++;
}
if (res == Integer.MAX_VALUE){
return -1;
}
return res;
}
}