给定一个由N 个节点和M 条边、一个源顶点、一个目标顶点和一个整数K组成的加权图,任务是在图中找到从源到目的地的第K个最大权重的路径。
例子:
Input: N = 7, M = 8, source = 0, destination = 6, K = 3, Edges[][] = {{0, 1, 10}, {1, 2, 10}, {2, 3, 10}, {0, 3, 40}, {3, 4, 2}, {4, 5, 3}, {5, 6, 3}, {4, 6, 8}, {2, 5, 5}}
Output: 0 1 2 3 4 6
Explanation: A total of 4 paths exists from the source to the destination:
Path: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6. Weight = 38.
Path: 0 ->1 -> 2 -> 3 -> 6. Weight = 40.
Path: 0 -> 3 -> 4 -> 5 -> 6. Weight = 48.
Path: 0 -> 3 -> 4 -> 6. Weight = 50.
The 3rd largest weighted path is the path with weight 40. Hence, the path having weight 40 is the output.
Input: N = 2, M = 1, source = 0, destination = 1, K = 1, Edges[][] = {{0 1 25}},
Output: 0 1
方法:可以通过查找从给定源到目的地的所有路径并使用优先级队列找到第 K个最大权重来解决给定问题。请按照以下步骤解决问题:
- 初始化邻接列表以从给定的边Edges[][]集合创建图。
- 使用优先级队列初始化最大堆,比如PQ作为大小为K的最小堆,以将路径权重和路径存储为从源到目标的字符串。
- 初始化一个数组visited[] ,以标记一个顶点是否被访问过。
- 遍历图形以查找从源到目标的所有路径。
- 创建一个实用程序类 Pair 作为psf和wsf ,分别用于维护到目前为止获得的路径和权重。
- 在优先级队列中,执行以下操作:
- 如果队列少于K 个元素,则将该对添加到队列中。
- 否则,如果路径的当前权重大于队列前面的对的权重,则删除前面的元素,并将新对添加到队列中。
- 完成上述步骤后,优先级队列顶部的元素给出包含第K个最大权重路径的pair。因此,打印该路径。
下面是上述方法的实现:
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
// Edge class represents a source,
// destination, weight of the edge
class Edge {
// Source
int src;
// Destination
int nbr;
// Weight
int wt;
// Constructor to create an Edge
Edge(int src, int nbr, int wt)
{
this.src = src;
this.nbr = nbr;
this.wt = wt;
}
}
// Pair class
class Pair implements Comparable {
// Weight so far
int wsf;
// Path so far
String psf;
// Constructor to create a Pair
Pair(int wsf, String psf)
{
this.wsf = wsf;
this.psf = psf;
}
// Function to sort in increasing
// order of weights
public int compareTo(Pair o)
{
return this.wsf - o.wsf;
}
}
class GFG {
// Intializing the priority queue
static PriorityQueue pq
= new PriorityQueue<>();
// Function to find the path from src to
// dest with Kth largest weight in the graph
public static void kthLargest(
ArrayList[] graph,
int src, int dest,
boolean[] visited, int k,
String psf, int wsf)
{
// Base Case: When the
// destination has been reached
if (src == dest) {
// If pq has at most K elements
if (pq.size() < k) {
pq.add(new Pair(wsf, psf));
}
else if (wsf > pq.peek().wsf) {
pq.remove();
pq.add(new Pair(wsf, psf));
}
return;
}
// Mark the source node as visited
visited[src] = true;
// Iterating over all
// the neighbours of src
for (Edge e : graph[src]) {
// If neighbour is not visited
if (!visited[e.nbr]) {
kthLargest(graph, e.nbr,
dest, visited,
k, psf + e.nbr,
wsf + e.wt);
}
}
// Mark src as unvisited
visited[src] = false;
}
// Function to add edges
public static void addEdges(
ArrayList[] graph)
{
// Adding a bidirectional edge
graph[0].add(new Edge(0, 1, 10));
graph[1].add(new Edge(1, 0, 10));
graph[1].add(new Edge(1, 2, 10));
graph[2].add(new Edge(2, 1, 10));
graph[2].add(new Edge(2, 3, 10));
graph[3].add(new Edge(3, 2, 10));
graph[0].add(new Edge(0, 3, 40));
graph[3].add(new Edge(3, 0, 40));
graph[3].add(new Edge(3, 4, 2));
graph[4].add(new Edge(4, 3, 2));
graph[4].add(new Edge(4, 5, 3));
graph[5].add(new Edge(5, 4, 3));
graph[5].add(new Edge(5, 6, 3));
graph[6].add(new Edge(6, 5, 3));
graph[4].add(new Edge(4, 6, 8));
graph[6].add(new Edge(6, 4, 8));
}
// Utility function to find the
// path with Kth largest weight
public static void kthLargestPathUtil(
int N, int M, int src,
int dest, int k)
{
@SuppressWarnings("unchecked")
// Arraylist to store edges
ArrayList[] graph
= new ArrayList[2 * N];
for (int i = 0; i < 2 * N; i++) {
graph[i] = new ArrayList<>();
}
// Function to add edges
addEdges(graph);
// Stores if a vertex is visited or not
boolean[] visited = new boolean[N];
kthLargest(graph, src, dest,
visited, k, src + "",
0);
// Stores the kth largest weighted path
String path = pq.peek().psf;
// Traversing path string
for (int i = 0;
i < path.length(); i++) {
System.out.print(
path.charAt(i) + " ");
}
}
// Driver Code
public static void main(String[] args)
{
// No of vertices and Edges
int N = 7, M = 8;
// Source vertex
int src = 0;
// Destination vertex
int dest = 6;
int k = 3;
kthLargestPathUtil(N, M, src,
dest, k);
}
}
时间复杂度: O(V + E)
辅助空间: O(V)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live