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 fights, 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
.
Example 1: Input: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 1 Output: 200 Explanation: The graph looks like this: The cheapest price from city0
to city2
with at most 1 stop costs 200, as marked red in the picture.
Example 2: Input: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 0 Output: 500 Explanation: The graph looks like this: The cheapest price from city0
to city2
with at most 0 stop costs 500, as marked blue in the picture.
Note:
- The number of nodes
n
will be in range[1, 100]
, with nodes labeled from0
ton
- 1
. - The size of
flights
will be in range[0, n * (n - 1) / 2]
. - The format of each flight will be
(src,
dst
, price)
. - The price of each flight will be in the range
[1, 10000]
. k
is in the range of[0, n - 1]
.- There will not be any duplicated flights or self cycles.
struct Node {
string path;int cnt;
int cost;
Node(string path, int cnt, int cost):path(path), cnt(cnt), cost(cost) {}
};
class Solution {
public:
int lastPos(string path) {
int pos = path.find_last_of(',');
return atoi( path.substr(pos+1).c_str() );
}
int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
set<string> visit;
map< pair<int, int>, int > mat;
map< int, vector<int> > edges;
for (int i = 0; i < flights.size(); i++) {
mat[ make_pair(flights[i][0], flights[i][1]) ] = flights[i][2];
if (edges.find(flights[i][0]) == edges.end()) {
edges[flights[i][0]] = vector<int>{flights[i][1]};
} else {
edges[flights[i][0]].push_back( flights[i][1] );
}
}
queue<Node>q;
int ans = INT_MAX;
for (int j = 0; j < edges[src].size(); j++) {
int i = edges[src][j];
if (i == dst) {
// cout << "ans:" << ans << " flights[src][i]:" << mat[make_pair(src, i)] << endl;
ans = min(ans, mat[make_pair(src, i)]);
}
string path = to_string(src) + "," + to_string(i);
visit.insert(path);
q.push( Node(path, 0, mat[make_pair(src, i)]) );
}
while (!q.empty()) {
Node tp = q.front();
// cout << "tp:" << tp.cnt << " ->" << tp.cost << endl;
q.pop();
int last = lastPos(tp.path);
if (tp.cnt >= K || last == dst || tp.cost >= ans) continue;
for (int j = 0; j < edges[last].size(); j++) {
int i = edges[last][j];
string path = tp.path + "," + to_string(i);
if (visit.find(path) != visit.end()) continue;
visit.insert(path);
if (i == dst) {
// cout << "ans:" << ans << " flights[last][i]:" << tp.cost + mat[make_pair(last, i)] << endl;
ans = min(ans, tp.cost + mat[make_pair(last, i)]);
} else {
q.push(Node( path, tp.cnt + 1, tp.cost + mat[make_pair(last, i)] ));
}
}
}
return ans==INT_MAX?-1:ans;
}
};