有 n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = { start(i), end(i), price(i) } ,表示该航班都从城市 start(i) 开始,以价格 price(i) 抵达 end(i)。 现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到一条中转的路线,使得从 src 到 dst 的 总价格最便宜 ,并返回该价格。 题目保证了这样的路线一定存在java代码
时间: 2024-03-10 18:50:00 浏览: 105
以下是使用Dijkstra算法解决该问题的Java代码实现:
```
import java.util.*;
class Solution {
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
// 构建邻接表
Map<Integer, List<int[]>> graph = new HashMap<>();
for (int[] flight : flights) {
int u = flight[0], v = flight[1], w = flight[2];
if (!graph.containsKey(u)) {
graph.put(u, new ArrayList<>());
}
graph.get(u).add(new int[]{v, w});
}
// 初始化距离数组
int[] dist = new int[n];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[src] = 0;
// 使用优先队列维护当前距离最小的点
Queue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
pq.offer(new int[]{0, src, k + 1});
// Dijkstra算法
while (!pq.isEmpty()) {
int[] cur = pq.poll();
int d = cur[0], u = cur[1], s = cur[2];
if (u == dst) {
return d;
}
if (s > 0) {
List<int[]> neighbors = graph.getOrDefault(u, new ArrayList<>());
for (int[] neighbor : neighbors) {
int v = neighbor[0], w = neighbor[1];
if (dist[u] != Integer.MAX_VALUE && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
pq.offer(new int[]{dist[v], v, s - 1});
}
}
}
}
return -1;
}
}
```
其中,优先队列中每个元素的格式为`{距离, 当前节点, 剩余中转次数}`,表示从源点到当前节点的距离、当前节点的编号以及还剩余的中转次数。在Dijkstra算法中,每次从优先队列中取出距离最小的节点进行扩展,并更新到其他节点的距离值。由于本题需要限制中转次数,因此需要在每次扩展节点时记录剩余的中转次数,并将其作为新元素加入优先队列中。
阅读全文