Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,31 @@
Given cities connected by flights [from,to,price], also given src, dst, & k:
Return cheapest price from src to dst with at most k stops

Dijkstra's but modified, normal won't work b/c will discard heap nodes w/o finishing
Modify: need to re-consider a node if dist from source is shorter than what we recorded
But, if we encounter node already processed but # of stops from source is lesser,
Need to add it back to the heap to be considered again

Time: O(V^2 log V) -> V = number of cities
Space: O(V^2)
Minimized implementation of the Bellman-Ford algorithm.
Loop for #maximum-stops times and, for each flight, update the array of distances if
there's a new path from the destination to the source having lower cost than the current.
Time: O(k*n)
Space: O(n)
*/

class Solution {
public:
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
// build adjacency matrix
vector<vector<int>> adj(n, vector<int>(n));
for (int i = 0; i < flights.size(); i++) {
vector<int> flight = flights[i];
adj[flight[0]][flight[1]] = flight[2];
}

// shortest distances
vector<int> distances(n, INT_MAX);
distances[src] = 0;
// shortest steps
vector<int> currStops(n, INT_MAX);
currStops[src] = 0;

// priority queue -> (cost, node, stops)
priority_queue<vector<int>, vector<vector<int>>, greater<vector<int>>> pq;
pq.push({0, src, 0});

while (!pq.empty()) {
int cost = pq.top()[0];
int node = pq.top()[1];
int stops = pq.top()[2];
pq.pop();

// if destination is reached, return cost to get here
if (node == dst) {
return cost;
}

// if no more steps left, continue
if (stops == k + 1) {
continue;
}

// check & relax all neighboring edges
for (int neighbor = 0; neighbor < n; neighbor++) {
if (adj[node][neighbor] > 0) {
int currCost = cost;
int neighborDist = distances[neighbor];
int neighborWeight = adj[node][neighbor];

// check if better cost
int currDist = currCost + neighborWeight;
if (currDist < neighborDist || stops + 1 < currStops[neighbor]) {
pq.push({currDist, neighbor, stops + 1});
distances[neighbor] = currDist;
currStops[neighbor] = stops;
} else if (stops < currStops[neighbor]) {
// check if better steps
pq.push({currDist, neighbor, stops + 1});
}
currStops[neighbor] = stops;
}
vector<int> dist(n, INT_MAX);
dist[src] = 0;

for (int stops = 0; stops <= k; ++stops){
vector<int> tmp = dist;
for (auto& flight : flights){
int s = flight[0], d = flight[1], p = flight[2];
if (dist[s] == INT_MAX)
continue;
if (tmp[d] > dist[s] + p)
tmp[d] = dist[s] + p;
}
dist = tmp;
}

if (distances[dst] == INT_MAX) {
return -1;
}
return distances[dst];

return dist[dst] == INT_MAX ? -1 : dist[dst];
}
};