Кратчайший путь из одного источника между двумя городами
Дан граф из 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
Рекомендуется: сначала попробуйте свой подход в {IDE}, прежде чем переходить к решению.
Метод 1: использование поиска в глубину
- Исследуйте текущий узел и продолжайте изучать его дочерние элементы.
- Используйте карту, чтобы сохранить посещенный узел в паре с остановками и расстоянием в качестве значения.
- Разбейте дерево рекурсии, если ключ присутствует на карте.
- Найдите ответ (минимальную стоимость) для каждого дерева рекурсии и верните его.
Below is the implementation of our approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Structure to implement hashing to // stores pairs in map struct pair_hash { template < class T1, class T2> std:: size_t operator()( const std::pair<T1, T2>& pair) const { return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second); } }; // DFS memoization vector<vector< int > > adjMatrix; typedef std::pair< int , int > pair1; unordered_map<pair1, int , pair_hash> 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< int , int > 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<vector< int > >& flights, int src, int dst, int stops) { // Resize Adjacency Marix adjMatrix.resize(cities + 1, vector< int >(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<vector< int > > 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; } |
6
Сложность времени: O (V + E), где V - количество узлов, а E - ребра.
Вспомогательное пространство: O (V)
Метод 2: использование поиска в ширину
- Идея состоит в том, чтобы использовать очередь для выполнения обхода BFS.
- Выполните обход от текущего узла и вставьте корневой узел в очередь.
- Пройдите по очереди и исследуйте текущий узел и его братьев и сестер. Затем вставьте братьев и сестер узла в очередь.
- Изучая каждого брата и сестру, продолжайте вставлять записи в очередь, если стоимость меньше, и обновляйте минимальную стоимость.
- Выведите минимальную стоимость после указанного выше обхода.
Below is the implementation of our approach:
C++
// C++ program of the above approach #include <bits/stdc++.h> #include <iostream> #include <queue> #include <tuple> #include <unordered_map> using namespace std; // BSF Memoization typedef tuple< int , int , int > tupl; // Function to implement BFS int findCheapestPrice( int cities, vector<vector< int > >& flights, int src, int dst, int stops) { unordered_map< int , vector<pair< int , int > > > adjList; // Traverse flight[][] for ( auto flight : flights) { // Create Adjacency Matrix adjList[flight[0]].push_back( { flight[1], flight[2] }); } // < city, distancefromsource > pair queue<pair< int , int > > 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< int , int > 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<vector< int > > 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 (остановок * N * N), где N - произведение городов и размеров в очереди.
Вспомогательное пространство: O (N)
Метод 3: использование алгоритма Дейкстры
- Обновите расстояние всех вершин от источника.
- Вершины, которые не связаны напрямую с источником, помечаются бесконечностью, а вершины, которые напрямую связаны, обновляются с правильным расстоянием.
- Начните с источника и извлеките следующие min вершины. Это обеспечит минимальную стоимость.
- Выполняйте релаксацию краев на каждом шаге: D обозначает расстояние, а w обозначает веса
- Если D [u] + w (u, z) <D [z], то
- D [z] = D [u] + w (u, z)
Here is the implementation of our approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> #include <tuple> using namespace std; typedef tuple< int , int , int > tupl; long findCheapestPrice( int cities, vector<vector< int > >& flights, int src, int dst, int stops) { // Adjacency Matrix vector<vector<pair< int , int > > > 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<tupl, vector<tupl>, greater<tupl> > 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<vector< int > > 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 раз, мы будем делать это для заданного количества остановок.
Below is the implementation of the above approach
C++
// C++ program of the above Approach #include <bits/stdc++.h> #include <vector> using namespace std; // Function to find the cheapest cost // from source to destination using K stops int findCheapestPrice( int cities, vector<vector< int > >& flights, int src, int dst, int stops) { // Dstance from source to all other nodes vector< int > 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< int > 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<vector< int > > flights РЕКОМЕНДУЕМЫЕ СТАТЬИ |