📌  相关文章
📜  有向加权图中最多包含 K 个节点的给定节点之间路径的最小成本

📅  最后修改于: 2022-05-13 01:56:07.624000             🧑  作者: Mango

有向加权图中最多包含 K 个节点的给定节点之间路径的最小成本

给定一个由大小为n的二维数组graph[][]和 3 个整数src、dstk表示的有向加权图,分别表示源点、目标点和可用停靠点数。任务是最小化有向加权图中最多包含K个节点的两个节点之间的路径成本。如果没有这样的路线,则返回-1

例子:

方法:k1 ,因为到达目的地时,将消耗k+1 个站点。使用广度优先搜索运行 while 循环,直到队列变空。每次从队列中弹出所有元素并将k1并签入它们的相邻元素列表并检查它们之前没有被访问过或者它们的成本大于父节点的成本+该节点的成本,然后按价格[父] + 该节点的成本标记他们的价格。如果k变为0 ,则中断 while 循环,因为要么计算了成本,要么我们消耗了k+1 个停止。请按照以下步骤解决问题:

  • k的值增加1。
  • 初始化对adj[n]的向量并构造图的邻接表。
  • 用值-1初始化向量price[n]
  • 初始化队列对q[]。
  • 将对{src, 0}推入队列并将价格 [0]的值设置为0
  • 在while循环中遍历,直到队列变空并执行以下步骤:
    • 如果k等于0则中断。
    • 将变量sz初始化为队列的大小。
    • 在while循环中遍历,直到sz大于0并执行以下任务:
      • 将变量节点初始化为队列前对的第一个值,将成本初始化为队列前对的第二个值。
      • 使用变量it遍历范围[0, adj[node].size())并执行以下任务:
        • 如果price[it.first]等于-1cost + it.second小于price[it.first]则将 price [ it.first] 的值设置为cost + it.second并推动对{it.first , cost + it.second}进入队列。
    • k的值减1。
  • 执行上述步骤后,打印price[dst]的值作为答案。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the minimum cost
// from src to dst with at most k stops
int findCheapestCost(int n,
                     vector >& graph,
                     int src, int dst, int k)
{
    // Increase k by 1 Because on reaching
    // destination, k becomes k+1
    k = k + 1;
 
    // Making Adjacency List
    vector > adj[n];
 
    // U->{v, wt}
    for (auto it : graph) {
        adj[it[0]].push_back({ it[1], it[2] });
    }
 
    // Vector for Storing prices
    vector prices(n, -1);
 
    // Queue for storing vertex and cost
    queue > q;
 
    q.push({ src, 0 });
    prices[src] = 0;
 
    while (!q.empty()) {
 
        // If all the k stops are used,
        // then break
        if (k == 0)
            break;
 
        int sz = q.size();
        while (sz--) {
            int node = q.front().first;
            int cost = q.front().second;
            q.pop();
 
            for (auto it : adj[node]) {
                if (prices[it.first] == -1
                    or cost + it.second
                           < prices[it.first]) {
                    prices[it.first] = cost + it.second;
                    q.push({ it.first, cost + it.second });
                }
            }
        }
        k--;
    }
    return prices[dst];
}
 
// Driver Code
int main()
{
    int n = 6;
    vector > graph
        = { { 0, 1, 10 }, { 1, 2, 20 }, { 2, 5, 30 }, { 1, 3, 10 }, { 3, 4, 10 }, { 4, 5, 10 } };
 
    int src = 0;
    int dst = 5;
    int k = 2;
    cout << findCheapestCost(n, graph, src, dst, k)
         << endl;
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
  static class pair
  {
    int first, second;
    public pair(int first, int second) 
    {
      this.first = first;
      this.second = second;
    }   
  }
  // Function to find the minimum cost
  // from src to dst with at most k stops
  static int findCheapestCost(int n,
                              int[][] graph,
                              int src, int dst, int k)
  {
    // Increase k by 1 Because on reaching
    // destination, k becomes k+1
    k = k + 1;
 
    // Making Adjacency List
    Vector []adj = new Vector[n];
    for (int i = 0; i < adj.length; i++)
      adj[i] = new Vector();
 
    // U.{v, wt}
    for (int it[] : graph) {
      adj[it[0]].add(new pair( it[1], it[2] ));
    }
 
    // Vector for Storing prices
    int []prices = new int[n];
    Arrays.fill(prices, -1);
 
    // Queue for storing vertex and cost
    Queue q = new LinkedList<>();
 
    q.add(new pair( src, 0 ));
    prices[src] = 0;
 
    while (!q.isEmpty()) {
 
      // If all the k stops are used,
      // then break
      if (k == 0)
        break;
 
      int sz = q.size();
      while (sz-- >0) {
        int node = q.peek().first;
        int cost = q.peek().second;
        q.remove();
 
        for (pair it : adj[node]) {
          if (prices[it.first] == -1
              || cost + it.second
              < prices[it.first]) {
            prices[it.first] = cost + it.second;
            q.add(new pair( it.first, cost + it.second ));
          }
        }
      }
      k--;
    }
    return prices[dst];
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int n = 6;
    int[][] graph
      = { { 0, 1, 10 }, { 1, 2, 20 }, { 2, 5, 30 }, { 1, 3, 10 }, { 3, 4, 10 }, { 4, 5, 10 } };
 
    int src = 0;
    int dst = 5;
    int k = 2;
    System.out.print(findCheapestCost(n, graph, src, dst, k)
                     +"\n");
 
  }
}
 
// This code is contributed by 29AjayKumar


Python3
# python3 program for the above approach
from collections import deque
 
# Function to find the minimum cost
# from src to dst with at most k stops
def findCheapestCost(n, graph, src, dst, k):
 
    # Increase k by 1 Because on reaching
    # destination, k becomes k+1
    k = k + 1
 
    # Making Adjacency List
    adj = [[] for _ in range(n)]
 
    # U->{v, wt}
    for it in graph:
        adj[it[0]].append([it[1], it[2]])
 
    # Vector for Storing prices
    prices = [-1 for _ in range(n)]
 
    # Queue for storing vertex and cost
    q = deque()
 
    q.append([src, 0])
    prices[src] = 0
 
    while (len(q) != 0):
 
        # If all the k stops are used,
        # then break
        if (k == 0):
            break
 
        sz = len(q)
        while (True):
            sz -= 1
 
            pr = q.popleft()
 
            node = pr[0]
            cost = pr[1]
 
            for it in adj[node]:
                if (prices[it[0]] == -1
                        or cost + it[1]
                        < prices[it[0]]):
                    prices[it[0]] = cost + it[1]
                    q.append([it[0], cost + it[1]])
 
            if sz == 0:
                break
        k -= 1
 
    return prices[dst]
 
# Driver Code
if __name__ == "__main__":
 
    n = 6
    graph = [
            [0, 1, 10],
            [1, 2, 20],
            [2, 5, 30],
            [1, 3, 10],
            [3, 4, 10],
            [4, 5, 10]]
 
    src = 0
    dst = 5
    k = 2
    print(findCheapestCost(n, graph, src, dst, k))
 
    # This code is contributed by rakeshsahni



输出
60

时间复杂度: O(n*k)
辅助空间: O(n)