📌  相关文章
📜  通过 K 个中间节点从源节点到目的节点的最小成本路径

📅  最后修改于: 2021-09-07 02:15:40             🧑  作者: Mango

给定一个由N个顶点和M 个加权边组成的 Graph 和一个数组edge[][] ,每一行代表由边和边的权重连接的两个顶点,任务是找到具有最小总和的路径从给定源顶点src到给定目标顶点dst 的权重,由K 个中间顶点组成。如果不存在这样的路径,则打印-1

例子:

方法:给定的问题可以使用优先队列解决并执行 BFS。请按照以下步骤解决此问题:

  1. 初始化一个优先级队列来存储元组{cost to reach this vertex, vertex, number ofstops}
  2. 推送{0, src, k+1}作为第一个起点。
  3. 弹出优先队列的顶部元素。如果所有停靠点都用完,则重复此步骤。
  4. 如果到达目的地,则打印到达当前顶点的成本。
  5. 否则,找到这个顶点的邻居,它需要最小的成本才能到达那个顶点。将其推入优先队列
  6. 从第 2步开始重复。
  7. 如果执行上述步骤后没有找到路径,则打印-1

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the minimum cost path
// from the source vertex to destination
// vertex via K intermediate vertices
int leastWeightedSumPath(int n,
                         vector >& edges,
                         int src, int dst, int K)
{
    // Initialize the adjacency list
    unordered_map > >
        graph;
 
    // Generate the adjacency list
    for (vector& edge : edges) {
        graph[edge[0]].push_back(
            make_pair(edge[1], edge[2]));
    }
 
    // Initialize the minimum priority queue
    priority_queue, vector >,
                   greater > >
        pq;
 
    // Stores the minimum cost to
    // travel between vertices via
    // K intermediate nodes
    vector > costs(n,
                               vector(
                                   K + 2, INT_MAX));
 
    costs[src][K + 1] = 0;
 
    // Push the starting vertex,
    // cost to reach and the number
    // of remaining vertices
    pq.push({ 0, src, K + 1 });
 
    while (!pq.empty()) {
        // Pop the top element
        // of the stack
        auto top = pq.top();
 
        pq.pop();
 
        // If destination is reached
        if (top[1] == dst)
 
            // Return the cost
            return top[0];
 
        // If all stops are exhausted
        if (top[2] == 0)
            continue;
 
        // Find the neighbour with minimum cost
        for (auto neighbor : graph[top[1]]) {
 
            // Pruning
            if (costs[neighbor.first][top[2] - 1]
                < neighbor.second + top[0]) {
                continue;
            }
 
            // Update cost
            costs[neighbor.first][top[2] - 1]
                = neighbor.second + top[0];
 
            // Update priority queue
            pq.push({ neighbor.second + top[0],
                      neighbor.first, top[2] - 1 });
        }
    }
 
    // If no path exists
    return -1;
}
 
// Driver Code
int main()
{
    int n = 3, src = 0, dst = 2, k = 1;
    vector > edges
        = { { 0, 1, 100 },
            { 1, 2, 100 },
            { 0, 2, 500 } };
 
    // Function Call to find the path
    // from src to dist via k nodes
    // having least sum of weights
    cout << leastWeightedSumPath(n, edges,
                                 src, dst, k);
 
    return 0;
}


Python3
# Python3 program for the above approach
 
# Function to find the minimum cost path
# from the source vertex to destination
# vertex via K intermediate vertices
def leastWeightedSumPath(n, edges, src, dst, K):
    graph = [[] for i in range(3)]
 
    # Generate the adjacency list
    for edge in edges:
        graph[edge[0]].append([edge[1], edge[2]])
 
    # Initialize the minimum priority queue
    pq = []
 
    # Stores the minimum cost to
    # travel between vertices via
    # K intermediate nodes
    costs = [[10**9 for i in range(K + 2)] for i in range(n)]
 
    costs[src][K + 1] = 0
 
    # Push the starting vertex,
    # cost to reach and the number
    # of remaining vertices
    pq.append([ 0, src, K + 1 ])
 
    pq = sorted(pq)[::-1]
 
    while (len(pq) > 0):
       
        # Pop the top element
        # of the stack
        top = pq[-1]
 
        del pq[-1]
 
        # If destination is reached
        if (top[1] == dst):
           
            # Return the cost
            return top[0]
 
        # If all stops are exhausted
        if (top[2] == 0):
            continue
 
        # Find the neighbour with minimum cost
        for neighbor in graph[top[1]]:
 
            # Pruning
            if (costs[neighbor[0]][top[2] - 1] < neighbor[1] + top[0]):
                continue
 
            # Update cost
            costs[neighbor[0]][top[2] - 1] = neighbor[1]+ top[0]
 
            # Update priority queue
            pq.append([neighbor[1]+ top[0],neighbor[0], top[2] - 1])
        pq = sorted(pq)[::-1]
 
    # If no path exists
    return -1
 
# Driver Code
if __name__ == '__main__':
    n, src, dst, k = 3, 0, 2, 1
    edges = [ [ 0, 1, 100 ],
            [ 1, 2, 100 ],
            [ 0, 2, 500 ] ]
 
    # Function Call to find the path
    # from src to dist via k nodes
    # having least sum of weights
    print (leastWeightedSumPath(n, edges, src, dst, k))
 
# This code is contributed by mohit kumar 29.


输出:
200

时间复杂度: O(N * log N)
辅助空间:O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live