给定一个N节点和E边的图,形式为{U, V, W} ,使得U 和 V之间存在权重为W 的边。你得到一个整数K和源src和目标dst 。任务是找到从给定源到目的地的K 个停靠点的最便宜的成本路径。
例子:
Input: N = 3, edges = [[0, 1, 100], [1, 2, 100], [0, 2, 500]], src = 0, dst = 2, k = 1
Output: 200
Explanation:
The Cheapest Price is from City 0 to City 2. With just one stop, it just costs 200 which is our Output.
Input: N = 3, edges = [[0, 1, 100], [1, 2, 100], [0, 2, 500]], src = 0, dst = 2, k = 0
Output: 500
方法 1:使用深度优先搜索
- 探索当前节点并继续探索其子节点。
- 使用地图将访问过的节点与停靠点和距离成对存储为值。
- 如果键存在于映射中,则中断递归树。
- 为每个递归树找到答案(最小成本)并返回它。
下面是我们方法的实现。
C++
// C++ program for the above approach
#include
using namespace std;
// Structure to implement hashing to
// stores pairs in map
struct pair_hash {
template
std::size_t
operator()(const std::pair& pair) const
{
return std::hash()(pair.first)
^ std::hash()(pair.second);
}
};
// DFS memoization
vector > adjMatrix;
typedef std::pair pair1;
unordered_map mp;
// Function to implement DFS Traversal
long DFSUtility(int node, int stops,
int dst, int cities)
{
// Base Case
if (node == dst)
return 0;
if (stops < 0) {
return INT_MAX;
}
pair key(node, stops);
// Find value with key in a map
if (mp.find(key) != mp.end()) {
return mp[key];
}
long ans = INT_MAX;
// Traverse adjacency matrix of
// source node
for (int neighbour = 0;
neighbour < cities;
++neighbour) {
long weight
= adjMatrix[node][neighbour];
if (weight > 0) {
// Recursive DFS call for
// child node
long minVal
= DFSUtility(neighbour,
stops - 1,
dst, cities);
if (minVal + weight > 0)
ans = min(ans,
minVal
+ weight);
}
}
mp[key] = ans;
// Return ans
return ans;
}
// Function to find the cheapest price
// from given source to destination
int findCheapestPrice(int cities,
vector >& flights,
int src, int dst, int stops)
{
// Resize Adjacency Marix
adjMatrix.resize(cities + 1,
vector(cities + 1, 0));
// Traverse flight[][]
for (auto item : flights) {
// Create Adjacency Matrix
adjMatrix[item[0]][item[1]] = item[2];
}
// DFS Call to find shortest path
long ans = DFSUtility(src, stops,
dst, cities);
// Return the cost
return ans >= INT_MAX ? -1 : (int)ans;
;
}
// Driver Code
int main()
{
// Input flight : {Source,
// Destination, Cost}
vector > flights
= { { 4, 1, 1 }, { 1, 2, 3 }, { 0, 3, 2 }, { 0, 4, 10 }, { 3, 1, 1 }, { 1, 4, 3 } };
// vec, n, stops, src, dst
int stops = 2;
int totalCities = 5;
int sourceCity = 0;
int destCity = 4;
// Function Call
long ans = findCheapestPrice(
totalCities, flights,
sourceCity, destCity,
stops);
cout << ans;
return 0;
}
C++
// C++ program of the above approach
#include
#include
#include
#include
#include
using namespace std;
// BSF Memoization
typedef tuple tupl;
// Function to implement BFS
int findCheapestPrice(int cities,
vector >& flights,
int src, int dst, int stops)
{
unordered_map > >
adjList;
// Traverse flight[][]
for (auto flight : flights) {
// Create Adjacency Matrix
adjList[flight[0]].push_back(
{ flight[1], flight[2] });
}
// < city, distancefromsource > pair
queue >
q;
q.push({ src, 0 });
// Store the Result
int srcDist = INT_MAX;
// Traversing the Matrix
while (!q.empty() && stops-- >= 0) {
int qSize = q.size();
for (int i = 0; i < qSize; i++) {
pair curr = q.front();
q.pop();
for (auto next : adjList[curr.first]) {
// If source distance is already
// least the skip this iteration
if (srcDist < curr.second
+ next.second)
continue;
q.push({ next.first,
curr.second
+ next.second });
if (dst == next.first) {
srcDist = min(
srcDist, curr.second
+ next.second);
}
}
}
}
// Returning the Answer
return srcDist == INT_MAX ? -1 : srcDist;
}
// Driver Code
int main()
{
// Input flight : {Source,
// Destination, Cost}
vector > flights
= { { 4, 1, 1 }, { 1, 2, 3 }, { 0, 3, 2 }, { 0, 4, 10 }, { 3, 1, 1 }, { 1, 4, 3 } };
// vec, n, stops, src, dst
int stops = 2;
int totalCities = 5;
// Given source and destination
int sourceCity = 0;
int destCity = 4;
// Function Call
long ans = findCheapestPrice(
totalCities, flights,
sourceCity, destCity,
stops);
cout << ans;
return 0;
}
C++
// C++ program for the above approach
#include
#include
using namespace std;
typedef tuple tupl;
long findCheapestPrice(int cities,
vector >& flights,
int src, int dst, int stops)
{
// Adjacency Matrix
vector > > adjList(cities);
// Traverse flight[][]
for (auto flight : flights) {
// Create Adjacency Matrix
adjList[flight[0]].push_back(
{ flight[1], flight[2] });
}
// Implementing Priority Queue
priority_queue,
greater >
pq;
tupl t = make_tuple(0, src, stops);
pq.push(t);
// While PQ is not empty
while (!pq.empty()) {
tupl t = pq.top();
pq.pop();
if (src == dst)
return 0;
int cost = get<0>(t);
int current = get<1>(t);
int stop = get<2>(t);
if (current == dst)
// Return the Answer
return cost;
if (stop >= 0) {
for (auto next : adjList[current]) {
tupl t = make_tuple((cost
+ next.second),
next.first,
stop - 1);
pq.push(t);
}
}
}
return -1;
}
int main()
{
// Input flight : {Source,
// Destination, Cost}
vector > flights
= { { 4, 1, 1 }, { 1, 2, 3 }, { 0, 3, 2 }, { 0, 4, 10 }, { 3, 1, 1 }, { 1, 4, 3 } };
// vec, n, stops, src, dst
int stops = 2;
int totalCities = 5;
// Given source and destination
int sourceCity = 0;
int destCity = 4;
// Function Call
long ans = findCheapestPrice(
totalCities, flights,
sourceCity, destCity, stops);
cout << ans;
return 0;
}
C++
// C++ program of the above Approach
#include
#include
using namespace std;
// Function to find the cheapest cost
// from source to destination using K stops
int findCheapestPrice(int cities,
vector >& flights,
int src, int dst, int stops)
{
// Distance from source to all other nodes
vector dist(cities, INT_MAX);
dist[src] = 0;
// Do relaxation for V-1 vertices
// here we need for K stops so we
// will do relaxation for k+1 stops
for (int i = 0; i <= stops; i++) {
vector intermediate(dist);
for (auto flight : flights) {
if (dist[flight[0]] != INT_MAX) {
intermediate[flight[1]]
= min(intermediate[flight[1]],
dist[flight[0]]
+ flight[2]);
}
}
// Update the distance vector
dist = intermediate;
}
// Return the final cost
return dist[dst] == INT_MAX ? -1 : dist[dst];
}
// Driver Code
int main()
{
// Input flight : {Source, Destination, Cost}
vector > flights
= { { 4, 1, 1 }, { 1, 2, 3 }, { 0, 3, 2 }, { 0, 4, 10 }, { 3, 1, 1 }, { 1, 4, 3 } };
// vec, n, stops, src, dst
int stops = 2;
int totalCities = 5;
// Given source and destination
int sourceCity = 0;
int destCity = 4;
// Function Call
long ans = findCheapestPrice(
totalCities, flights, sourceCity,
destCity, stops);
cout << ans;
return 0;
}
6
时间复杂度: O(V + E),其中 V 是节点数,E 是边。
辅助空间: O(V)
方法 2:使用广度优先 搜索
- 这个想法是使用 Queue 来执行 BFS Traversal。
- 从当前节点开始遍历,在队列中插入根节点。
- 遍历队列并探索当前节点及其兄弟节点。然后将节点的兄弟节点插入队列。
- 在探索每个兄弟并在成本较低时继续推送队列中的条目并更新最小成本。
- 打印上述遍历后的最小成本。
下面是我们方法的实现:
C++
// C++ program of the above approach
#include
#include
#include
#include
#include
using namespace std;
// BSF Memoization
typedef tuple tupl;
// Function to implement BFS
int findCheapestPrice(int cities,
vector >& flights,
int src, int dst, int stops)
{
unordered_map > >
adjList;
// Traverse flight[][]
for (auto flight : flights) {
// Create Adjacency Matrix
adjList[flight[0]].push_back(
{ flight[1], flight[2] });
}
// < city, distancefromsource > pair
queue >
q;
q.push({ src, 0 });
// Store the Result
int srcDist = INT_MAX;
// Traversing the Matrix
while (!q.empty() && stops-- >= 0) {
int qSize = q.size();
for (int i = 0; i < qSize; i++) {
pair curr = q.front();
q.pop();
for (auto next : adjList[curr.first]) {
// If source distance is already
// least the skip this iteration
if (srcDist < curr.second
+ next.second)
continue;
q.push({ next.first,
curr.second
+ next.second });
if (dst == next.first) {
srcDist = min(
srcDist, curr.second
+ next.second);
}
}
}
}
// Returning the Answer
return srcDist == INT_MAX ? -1 : srcDist;
}
// Driver Code
int main()
{
// Input flight : {Source,
// Destination, Cost}
vector > flights
= { { 4, 1, 1 }, { 1, 2, 3 }, { 0, 3, 2 }, { 0, 4, 10 }, { 3, 1, 1 }, { 1, 4, 3 } };
// vec, n, stops, src, dst
int stops = 2;
int totalCities = 5;
// Given source and destination
int sourceCity = 0;
int destCity = 4;
// Function Call
long ans = findCheapestPrice(
totalCities, flights,
sourceCity, destCity,
stops);
cout << ans;
return 0;
}
6
时间复杂度: O(Stops* N * N) 其中 N 是队列中城市和规模的乘积
辅助空间: O(N)
方法 3:使用Dijkstra 算法
- 更新所有顶点到源的距离。
- 与源不直接相连的顶点用无穷大标记,直接相连的顶点用正确的距离更新。
- 从源开始,提取下一个最小顶点。这将确保最低成本。
- 在每一步做边缘松弛: D 表示距离, w 表示权重
- 如果 D[u] + w(u, z) < D[z] 那么
- D[z] = D[u] + w(u, z)
这是我们方法的实现:
C++
// C++ program for the above approach
#include
#include
using namespace std;
typedef tuple tupl;
long findCheapestPrice(int cities,
vector >& flights,
int src, int dst, int stops)
{
// Adjacency Matrix
vector > > adjList(cities);
// Traverse flight[][]
for (auto flight : flights) {
// Create Adjacency Matrix
adjList[flight[0]].push_back(
{ flight[1], flight[2] });
}
// Implementing Priority Queue
priority_queue,
greater >
pq;
tupl t = make_tuple(0, src, stops);
pq.push(t);
// While PQ is not empty
while (!pq.empty()) {
tupl t = pq.top();
pq.pop();
if (src == dst)
return 0;
int cost = get<0>(t);
int current = get<1>(t);
int stop = get<2>(t);
if (current == dst)
// Return the Answer
return cost;
if (stop >= 0) {
for (auto next : adjList[current]) {
tupl t = make_tuple((cost
+ next.second),
next.first,
stop - 1);
pq.push(t);
}
}
}
return -1;
}
int main()
{
// Input flight : {Source,
// Destination, Cost}
vector > flights
= { { 4, 1, 1 }, { 1, 2, 3 }, { 0, 3, 2 }, { 0, 4, 10 }, { 3, 1, 1 }, { 1, 4, 3 } };
// vec, n, stops, src, dst
int stops = 2;
int totalCities = 5;
// Given source and destination
int sourceCity = 0;
int destCity = 4;
// Function Call
long ans = findCheapestPrice(
totalCities, flights,
sourceCity, destCity, stops);
cout << ans;
return 0;
}
6
时间复杂度: O(E+V log V),其中 V 是节点数,E 是边。
辅助空间: O(V)
方法 4:使用Bellmon Ford
- 将源到所有顶点的距离初始化为无穷大,将到源本身的距离初始化为 0。
- 在每一步做边缘松弛:D 表示距离,w 表示权重
- 如果 D[u] + w(u, z) < D[z] 那么 D[z] = D[u] + w(u, z)
- 该算法已被修改以解决给定的问题,而不是放松图 V-1 次,我们将针对给定的停止次数进行处理。
下面是上述方法的实现
C++
// C++ program of the above Approach
#include
#include
using namespace std;
// Function to find the cheapest cost
// from source to destination using K stops
int findCheapestPrice(int cities,
vector >& flights,
int src, int dst, int stops)
{
// Distance from source to all other nodes
vector dist(cities, INT_MAX);
dist[src] = 0;
// Do relaxation for V-1 vertices
// here we need for K stops so we
// will do relaxation for k+1 stops
for (int i = 0; i <= stops; i++) {
vector intermediate(dist);
for (auto flight : flights) {
if (dist[flight[0]] != INT_MAX) {
intermediate[flight[1]]
= min(intermediate[flight[1]],
dist[flight[0]]
+ flight[2]);
}
}
// Update the distance vector
dist = intermediate;
}
// Return the final cost
return dist[dst] == INT_MAX ? -1 : dist[dst];
}
// Driver Code
int main()
{
// Input flight : {Source, Destination, Cost}
vector > flights
= { { 4, 1, 1 }, { 1, 2, 3 }, { 0, 3, 2 }, { 0, 4, 10 }, { 3, 1, 1 }, { 1, 4, 3 } };
// vec, n, stops, src, dst
int stops = 2;
int totalCities = 5;
// Given source and destination
int sourceCity = 0;
int destCity = 4;
// Function Call
long ans = findCheapestPrice(
totalCities, flights, sourceCity,
destCity, stops);
cout << ans;
return 0;
}
6
时间复杂度: O(E*V),其中 V 是节点数,E 是边。
辅助空间: O(V)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。