Given a weighted graph consisting of N nodes and M edges, a source vertex, a destination vertex, and an integer K, the task is to find the path with Kth largest weight from source to destination in the graph.
Examples:
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
Approach: The given problem can be solved by finding all the paths from a given source to a destination and using a Priority Queue to find the Kth largest weight. Follow the steps below to solve the problem:
- Initialize an adjacency list to create a graph from the given set of edges Edges[][].
- Initialize a Max-Heap using a priority queue, say PQ as a Min-Heap of size K, to store path weight and path as a string from source to destination.
- Initialize an array visited[], to mark if a vertex is visited or not.
- Traverse the graph to find all paths from source to destination.
- Create a utility class Pair as psf and wsf, for maintaining path and weight obtained so far respectively.
- In the priority queue, perform the following operations:
- After completing the above steps, the element at the top of the priority queue gives the pair containing the Kth largest weight path. Therefore, print that path.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Edge {
public :
int src;
int nbr;
int wt;
Edge( int srcc, int nbrr, int wtt)
{
src = srcc;
nbr = nbrr;
wt = wtt;
}
};
priority_queue<pair< int , string> > pq;
void kthLargest(vector<Edge> graph[], int src, int dest,
bool visited[], int k, string psf, int wsf)
{
if (src == dest) {
if (pq.size() < k) {
pq.push({ -wsf, psf });
}
else if (-wsf > pq.top().first) {
pq.pop();
pq.push({ -wsf, psf });
}
return ;
}
visited[src] = true ;
for (Edge e : graph[src]) {
if (!visited[e.nbr]) {
kthLargest(graph, e.nbr, dest, visited, k,
psf + to_string(e.nbr), wsf + e.wt);
}
}
visited[src] = false ;
}
void addEdges(vector<Edge> graph[])
{
Edge ob1(0, 1, 10);
Edge ob2(1, 0, 10);
Edge ob3(1, 2, 10);
Edge ob4(1, 2, 10);
Edge ob5(2, 3, 10);
Edge ob6(3, 2, 10);
Edge ob7(0, 3, 40);
Edge ob8(3, 0, 40);
Edge ob9(3, 4, 2);
Edge ob10(4, 3, 2);
Edge ob11(4, 5, 3);
Edge ob12(5, 4, 3);
Edge ob13(5, 6, 3);
Edge ob14(6, 5, 3);
Edge ob15(4, 6, 8);
Edge ob16(6, 4, 8);
graph[0].push_back(ob1);
graph[1].push_back(ob2);
graph[1].push_back(ob3);
graph[2].push_back(ob4);
graph[2].push_back(ob5);
graph[3].push_back(ob6);
graph[0].push_back(ob7);
graph[3].push_back(ob8);
graph[3].push_back(ob9);
graph[4].push_back(ob10);
graph[4].push_back(ob11);
graph[5].push_back(ob12);
graph[5].push_back(ob13);
graph[6].push_back(ob14);
graph[4].push_back(ob15);
graph[6].push_back(ob16);
}
void kthLargestPathUtil( int N, int M, int src, int dest,
int k)
{
vector<Edge> graph[2 * N];
addEdges(graph);
bool visited[N];
kthLargest(graph, src, dest, visited, k, src + "" , 0);
string path = pq.top().second;
for ( int i = 0; i < path.length(); i++) {
cout << path[i] << " " ;
}
}
int main()
{
int N = 7, M = 8;
int src = 0;
int dest = 6;
int k = 3;
kthLargestPathUtil(N, M, src, dest, k);
}
|
Java
import java.io.*;
import java.util.*;
class Edge {
int src;
int nbr;
int wt;
Edge( int src, int nbr, int wt)
{
this .src = src;
this .nbr = nbr;
this .wt = wt;
}
}
class Pair implements Comparable<Pair> {
int wsf;
String psf;
Pair( int wsf, String psf)
{
this .wsf = wsf;
this .psf = psf;
}
public int compareTo(Pair o)
{
return this .wsf - o.wsf;
}
}
class GFG {
static PriorityQueue<Pair> pq
= new PriorityQueue<>();
public static void kthLargest(
ArrayList<Edge>[] graph,
int src, int dest,
boolean [] visited, int k,
String psf, int wsf)
{
if (src == dest) {
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 ;
}
visited[src] = true ;
for (Edge e : graph[src]) {
if (!visited[e.nbr]) {
kthLargest(graph, e.nbr,
dest, visited,
k, psf + e.nbr,
wsf + e.wt);
}
}
visited[src] = false ;
}
public static void addEdges(
ArrayList<Edge>[] graph)
{
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 ));
}
public static void kthLargestPathUtil(
int N, int M, int src,
int dest, int k)
{
@SuppressWarnings ( "unchecked" )
ArrayList<Edge>[] graph
= new ArrayList[ 2 * N];
for ( int i = 0 ; i < 2 * N; i++) {
graph[i] = new ArrayList<>();
}
addEdges(graph);
boolean [] visited = new boolean [N];
kthLargest(graph, src, dest,
visited, k, src + "" ,
0 );
String path = pq.peek().psf;
for ( int i = 0 ;
i < path.length(); i++) {
System.out.print(
path.charAt(i) + " " );
}
}
public static void main(String[] args)
{
int N = 7 , M = 8 ;
int src = 0 ;
int dest = 6 ;
int k = 3 ;
kthLargestPathUtil(N, M, src,
dest, k);
}
}
|
Python3
class Edge:
def __init__( self , src, nbr, wt):
self .src = src
self .nbr = nbr
self .wt = wt
class Pair:
def __init__( self , wsf, psf):
self .wsf = wsf
self .psf = psf
def __cmp__( self , other):
return self .wsf - other.wsf
def kthLargest(graph, src, dest, visited, k, psf, wsf):
if src = = dest:
if len (pq) < k:
pq.append(Pair(wsf, psf))
elif wsf > pq[ 0 ].wsf:
pq.pop( 0 )
pq.append(Pair(wsf, psf))
return
visited[src] = True
for i in range ( len (graph[src])):
e = graph[src][i]
if not visited[e.nbr]:
kthLargest(graph, e.nbr, dest, visited,
k, psf + str (e.nbr), wsf + e.wt)
visited[src] = False
def addEdges(graph):
graph[ 0 ].append(Edge( 0 , 1 , 10 ))
graph[ 1 ].append(Edge( 1 , 0 , 10 ))
graph[ 1 ].append(Edge( 1 , 2 , 10 ))
graph[ 2 ].append(Edge( 2 , 1 , 10 ))
graph[ 2 ].append(Edge( 2 , 3 , 10 ))
graph[ 3 ].append(Edge( 3 , 2 , 10 ))
graph[ 0 ].append(Edge( 0 , 3 , 40 ))
graph[ 3 ].append(Edge( 3 , 0 , 40 ))
graph[ 3 ].append(Edge( 3 , 4 , 2 ))
graph[ 4 ].append(Edge( 4 , 3 , 2 ))
graph[ 4 ].append(Edge( 4 , 5 , 3 ))
graph[ 5 ].append(Edge( 5 , 4 , 3 ))
graph[ 5 ].append(Edge( 5 , 6 , 3 ))
graph[ 6 ].append(Edge( 6 , 5 , 3 ))
graph[ 4 ].append(Edge( 4 , 6 , 8 ))
graph[ 6 ].append(Edge( 6 , 4 , 8 ))
def kthLargestPathUtil(N, M, src, dest, k):
graph = [[] for i in range ( 2 * N)]
addEdges(graph)
visited = [ False ] * N
global pq
pq = []
kthLargest(graph, src, dest, visited, k, str (src), 0 )
print (pq[ 0 ].psf)
if __name__ = = '__main__' :
N = 7
M = 8
src = 0
dest = 6
k = 3
kthLargestPathUtil(N, M, src, dest, k)
|
C#
using System;
using System.Collections.Generic;
public class Edge
{
public int src;
public int nbr;
public int wt;
public Edge( int src, int nbr, int wt)
{
this .src = src;
this .nbr = nbr;
this .wt = wt;
}
}
public class Pair : IComparable<Pair>
{
public int wsf;
public string psf;
public Pair( int wsf, string psf)
{
this .wsf = wsf;
this .psf = psf;
}
public int CompareTo(Pair o)
{
return this .wsf - o.wsf;
}
}
public class GFG
{
static SortedSet<Pair> pq = new SortedSet<Pair>(
Comparer<Pair>.Create((p1, p2) => p1.wsf.CompareTo(p2.wsf)));
public static void kthLargest(
List<Edge>[] graph,
int src, int dest,
bool [] visited, int k,
string psf, int wsf)
{
if (src == dest)
{
if (pq.Count < k)
{
pq.Add( new Pair(wsf, psf));
}
else if (wsf > pq.Min.wsf)
{
pq.Remove(pq.Min);
pq.Add( new Pair(wsf, psf));
}
return ;
}
visited[src] = true ;
foreach (Edge e in graph[src])
{
if (!visited[e.nbr])
{
kthLargest(graph, e.nbr, dest, visited, k, psf + e.nbr, wsf + e.wt);
}
}
visited[src] = false ;
}
public static void addEdges(List<Edge>[] graph)
{
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));
}
public static void kthLargestPathUtil( int N, int M, int src, int dest, int k)
{
List<Edge>[] graph = new List<Edge>[2 * N];
for ( int i = 0; i < 2 * N; i++)
{
graph[i] = new List<Edge>();
}
addEdges(graph);
bool [] visited = new bool [N];
kthLargest(graph, src, dest, visited, k, src + "" , 0);
string path = pq.Min.psf;
foreach ( char c in path)
{
Console.Write(c + " " );
}
}
public static void Main()
{
int N = 7, M = 8;
int src = 0;
int dest = 6;
int k = 3;
kthLargestPathUtil(N, M, src, dest, k);
}
}
|
Javascript
class Edge {
constructor(src, nbr, wt) {
this .src = src;
this .nbr = nbr;
this .wt = wt;
}
}
let pq = [];
let x = 5;
for (let i = 0; i < 3; i++) process.stdout.write(i + " " );
function kthLargest(graph, src, dest, visited, k, psf, wsf) {
if (src == dest) {
if (pq.length < k) {
pq.push([-wsf, psf]);
} else if (-wsf > pq[0][0]) {
pq.shift();
pq.push([-wsf, psf]);
}
return ;
}
visited[src] = true ;
for (let e of graph[src]) {
if (!visited[e.nbr]) {
kthLargest(
graph,
e.nbr,
dest,
visited,
k,
psf + e.nbr.toString(),
wsf + e.wt
);
}
}
visited[src] = false ;
}
function addEdges(graph) {
let ob1 = new Edge(0, 1, 10);
let ob2 = new Edge(1, 0, 10);
let ob3 = new Edge(1, 2, 10);
let ob4 = new Edge(1, 2, 10);
let ob5 = new Edge(2, 3, 10);
let ob6 = new Edge(3, 2, 10);
let ob7 = new Edge(0, 3, 40);
let ob8 = new Edge(3, 0, 40);
let ob9 = new Edge(3, 4, 2);
let ob10 = new Edge(4, 3, 2);
let ob11 = new Edge(4, 5, 3);
let ob12 = new Edge(5, 4, 3);
let ob13 = new Edge(5, 6, 3);
let ob14 = new Edge(6, 5, 3);
let ob15 = new Edge(4, 6, 8);
let ob16 = new Edge(6, 4, 8);
graph[0].push(ob1);
graph[1].push(ob2);
graph[1].push(ob3);
graph[2].push(ob4);
graph[2].push(ob5);
graph[3].push(ob6);
graph[0].push(ob7);
graph[3].push(ob8);
graph[3].push(ob9);
graph[4].push(ob10);
graph[4].push(ob11);
graph[5].push(ob12);
graph[5].push(ob13);
graph[6].push(ob14);
graph[4].push(ob15);
graph[6].push(ob16);
}
function kthLargestPathUtil(N, M, src, dest, k) {
let graph = new Array(2 * N).fill().map(() => []);
addEdges(graph);
let visited = new Array(N).fill( false );
kthLargest(graph, src, dest, visited, k, src.toString(), 0);
let path = pq[pq.length - 1][1];
for (let i = 1; i < path.length; i++) {
if (path[i] == x) continue ;
process.stdout.write(path[i] + " " );
}
}
let N = 7,
M = 8;
let src = 0;
let dest = 6;
let k = 3;
kthLargestPathUtil(N, M, src, dest, k);
|
Time Complexity: O(V + E) Auxiliary Space: O(V)
|