方法一:深度优先遍历(回溯算法)
说明:
- 航班没有重复,且不存在环路;
- 每个航班的价格范围是
[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;
}
}