给定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)
{
// Dstance 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:使用广度优先 搜索
- 这个想法是使用队列执行BFS遍历。
- 从当前节点执行遍历并将根节点插入队列。
- 遍历队列并浏览当前节点及其兄弟节点。然后将节点的同级节点插入队列。
- 在探索每个同级时,如果成本较低,则继续在队列中推送条目,并更新最低成本。
- 经过上述遍历后,打印最低成本。
下面是我们方法的实现:
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 [u] + w(u,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:使用贝尔蒙·福特
- 初始化从源到所有顶点的距离为无穷大,到源本身的距离为0。
- 在每个步骤进行边缘松弛:D表示距离,w表示权重
- 如果D [u] + w(u,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)
{
// Dstance 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)