Sum of shortest distance on source to destination and back having at least a common vertex

Given a directed weighted graph and the source and destination vertex. The task is to find the sum of shortest distance on the path going from source to destination and then from destination to source such that both the paths have at least a common vertex other than the source and the destination.Â
Note: On going from destination to source, all the directions of the edges are reversed.
Examples:Â
Â
Input: src = 0, des = 1Â
Â
Output: 17Â
Explanation:Â
Common vertex is 4 and path is 0 -> 4 -> 3 -> 1 -> 4 -> 0Â
Â
Â
Approach: The idea is to use Dijkstra’s algorithm. On finding the shortest path from source to destination and shortest path from destination to the source using Dijkstra’s algorithm, it may not result in a path where there is at least one node in common except the source and destination vertex.
Â
- Let s be the source vertex and d be destination vertex and v be the intermediate node common in both the paths from source to destination and destination to source. The shortest pair of paths, so that v is in intersection of this two paths is a path: s -> v -> d -> v -> s and it’s length isÂ
Â
dis[s][v] + dis[v][d] + dis[d][v] + dis[v][s]Â
Â
- Since s and d are fixed, just find v such that it gives shortest path.
- In order to find such v, follow the below steps:Â
- Find shortest distance from all vertices to s and d which gives us the values of dis[v][s] and dis[v][d]. For finding the shortest path from all the vertices to a given node refer Shortest paths from all vertices to a destination.
- Find shortest distance of all vertex from s and d which gives us d[s][v] and d[d][v].
- Iterate for all v and find minimum of d[s][v] + d[v][d] + d[d][v] + d[v][s].
Below is the implementation of the above approach:
Â
CPP
// CPP implementation of the approachÂ
#include <bits/stdc++.h>using namespace std;#define INF 0x3f3f3f3fÂ
// iPair represents the Integer Pairtypedef pair<int, int> iPair;Â
// This class represents// a directed graph using// adjacency list representationclass Graph {Â
    // Number of vertices    int V;Â
    // In a weighted graph, store vertex    // and weight pair for every edge    list<pair<int, int> >* adj;Â
public:    // Constructor    Graph(int V);Â
    // Function to add an edge to graph    void addEdge(int u, int v, int w);Â
    // Find shortest path from    // source vertex to all vertex    void shortestPath(int src,                      vector<int>& dist);};Â
// Allocates memory for adjacency listGraph::Graph(int V){Â Â Â Â this->V = V;Â Â Â Â adj = new list<iPair>[V];}Â
// Function to add an edge to the graphvoid Graph::addEdge(int u, int v, int w){Â Â Â Â adj[v].push_back(make_pair(u, w));}Â
// Function to find the shortest paths// from source to all other verticesvoid Graph::shortestPath(int src,                         vector<int>& dist){Â
    // Create a priority queue to    // store vertices that    // are being preprocessed    priority_queue<iPair,                   vector<iPair>,                   greater<iPair> >        pq;Â
    // Insert source itself in priority    // queue and initialize    // its distance as 0    pq.push(make_pair(0, src));    dist[src] = 0;Â
    // Loop till priority queue    // becomes empty (or all    // distances are not finalized)    while (!pq.empty()) {Â
        // The first vertex in pair        // is the minimum distance        // vertex, extract it from        // priority queue        int u = pq.top().second;        pq.pop();Â
        // 'i' is used to get all        // adjacent vertices of a vertex        list<pair<int, int> >::iterator i;        for (i = adj[u].begin(); i != adj[u].end(); ++i) {Â
            // Get vertex label and            // weight of current            // adjacent of u            int v = (*i).first;            int weight = (*i).second;Â
            // If there is shorted            // path to v through u            if (dist[v] > dist[u] + weight) {Â
                // Updating distance of v                dist[v] = dist[u] + weight;                pq.push(make_pair(dist[v], v));            }        }    }}Â
// Function to return the// required minimum pathint minPath(int V, int src, int des,            Graph g, Graph r){    // Create a vector for    // distances and    // initialize all distances    // as infinite (INF)Â
    // To store distance of all    // vertex from source    vector<int> dist(V, INF);Â
    // To store distance of all    // vertex from destination    vector<int> dist2(V, INF);Â
    // To store distance of source    // from all vertex    vector<int> dist3(V, INF);Â
    // To store distance of    // destination from all vertex    vector<int> dist4(V, INF);Â
    // Computing shortest path from    // source vertex to all vertices    g.shortestPath(src, dist);Â
    // Computing shortest path from    // destination vertex to all vertices    g.shortestPath(des, dist2);Â
    // Computing shortest path from    // all the vertices to source    r.shortestPath(src, dist3);Â
    // Computing shortest path from    // all the vertices to destination    r.shortestPath(des, dist4);Â
    // Finding the intermediate node (IN)    // such that the distance of path    // src -> IN -> des -> IN -> src is minimumÂ
    // To store the shortest distance    int ans = INT_MAX;Â
    for (int i = 0; i < V; i++) {Â
        // Intermediate node should not be        // the source and destination        if (i != des && i != src)            ans = min(                ans,                dist[i] + dist2[i]                    + dist3[i] + dist4[i]);    }Â
    // Return the minimum path required    return ans;}Â
// Driver codeint main(){Â
    // Create the graph    int V = 5;    int src = 0, des = 1;Â
    // To store the original graph    Graph g(V);Â
    // To store the reverse graph    // and compute distance from all    // vertex to a particular vertex    Graph r(V);Â
    // Adding edges    g.addEdge(0, 2, 1);    g.addEdge(0, 4, 5);    g.addEdge(1, 4, 1);    g.addEdge(2, 0, 10);    g.addEdge(2, 3, 5);    g.addEdge(3, 1, 1);    g.addEdge(4, 0, 5);    g.addEdge(4, 2, 100);    g.addEdge(4, 3, 5);Â
    // Adding edges in reverse direction    r.addEdge(2, 0, 1);    r.addEdge(4, 0, 5);    r.addEdge(4, 1, 1);    r.addEdge(0, 2, 10);    r.addEdge(3, 2, 5);    r.addEdge(1, 3, 1);    r.addEdge(0, 4, 5);    r.addEdge(2, 4, 100);    r.addEdge(3, 4, 5);Â
    cout << minPath(V, src, des, g, r);Â
    return 0;} |
Java
// Java implementation of the approachimport java.util.*;Â
// This class represents// a directed graph using// adjacency list representationclass Graph {         // Number of vertices    private int V;           // In a weighted graph, store vertex    // and weight pair for every edge    private List<List<iPair> > adj;Â
    public Graph(int V)    {        this.V = V;        adj = new ArrayList<>();        for (int i = 0; i < V; i++) {            adj.add(new ArrayList<>());        }    }   // Function to add an edge to graph    public void addEdge(int u, int v, int w)    {        adj.get(v).add(new iPair(u, w));    }   // Find shortest path from    // source vertex to all vertex    public void shortestPath(int src, List<Integer> dist)    {        PriorityQueue<iPair> pq = new PriorityQueue<>(            Comparator.comparingInt(ip -> ip.first));        pq.add(new iPair(0, src));        dist.set(src, 0);Â
        while (!pq.isEmpty()) {            int u = pq.poll().second;Â
            for (iPair i : adj.get(u)) {                int v = i.first;                int weight = i.second;Â
                if (dist.get(v) > dist.get(u) + weight) {                    dist.set(v, dist.get(u) + weight);                    pq.add(new iPair(dist.get(v), v));                }            }        }    }}// iPair represents the Integer Pairclass iPair {    int first, second;Â
    public iPair(int first, int second)    {        this.first = first;        this.second = second;    }}class Main {    static int INF = 0x3f3f3f3f; // Function to return the// required minimum path    public static int minPath(int V, int src, int des,                              Graph g, Graph r)    {          // Create a vector for    // distances and    // initialize all distances    // as infinite (INF)Â
    // To store distance of all    // vertex from source        List<Integer> dist            = new ArrayList<>(Collections.nCopies(V, INF));           // To store distance of all    // vertex from destination        List<Integer> dist2            = new ArrayList<>(Collections.nCopies(V, INF));                  // To store distance of source    // from all vertex        List<Integer> dist3            = new ArrayList<>(Collections.nCopies(V, INF));                    // To store distance of    // destination from all vertex        List<Integer> dist4            = new ArrayList<>(Collections.nCopies(V, INF));Â
       // Computing shortest path from    // source vertex to all vertices    g.shortestPath(src, dist);Â
    // Computing shortest path from    // destination vertex to all vertices    g.shortestPath(des, dist2);Â
    // Computing shortest path from    // all the vertices to source    r.shortestPath(src, dist3);Â
    // Computing shortest path from    // all the vertices to destination    r.shortestPath(des, dist4);Â
 // Finding the intermediate node (IN)    // such that the distance of path    // src -> IN -> des -> IN -> src is minimumÂ
    // To store the shortest distance        int ans = Integer.MAX_VALUE;Â
 // Intermediate node should not be        // the source and destination        for (int i = 0; i < V; i++) {            if (i != des && i != src) {                ans = Math.min(                    ans, dist.get(i) + dist2.get(i)                             + dist3.get(i) + dist4.get(i));            }        }Â
        return ans;    }// Driver Code    public static void main(String[] args)    {             // Create the graph        int V = 5, src = 0, des = 1;             // To store the original graph        Graph g = new Graph(V);                     // To store the reverse graph    // and compute distance from all    // vertex to a particular vertex        Graph r = new Graph(V);Â
  // Adding edges        g.addEdge(0, 2, 1);        g.addEdge(0, 4, 5);        g.addEdge(1, 4, 1);        g.addEdge(2, 0, 10);        g.addEdge(2, 3, 5);        g.addEdge(3, 1, 1);        g.addEdge(4, 0, 5);        g.addEdge(4, 2, 100);        g.addEdge(4, 3, 5);Â
    // Adding edges in reverse direction        r.addEdge(2, 0, 1);        r.addEdge(4, 0, 5);        r.addEdge(4, 1, 1);        r.addEdge(0, 2, 10);        r.addEdge(3, 2, 5);        r.addEdge(1, 3, 1);        r.addEdge(0, 4, 5);        r.addEdge(2, 4, 100);        r.addEdge(3, 4, 5);Â
        System.out.println(minPath(V, src, des, g, r));    }} |
Python3
# Python implementation of the approachfrom typing import Listfrom queue import PriorityQueuefrom sys import maxsize as INT_MAXINF = 0x3f3f3f3fÂ
# This class represents# a directed graph using# adjacency list representationclass Graph:Â Â Â Â def __init__(self, V: int) -> None:Â
        # Number of vertices        self.V = VÂ
        # In a weighted graph, store vertex        # and weight pair for every edge        self.adj = [[] for _ in range(V)]Â
    # Function to add an edge to the graph    def addEdge(self, u: int, v: int, w: int) -> None:        self.adj[v].append((u, w))Â
    # Function to find the shortest paths    # from source to all other vertices    def shortestPath(self, src: int, dist: List[int]) -> None:Â
        # Create a priority queue to        # store vertices that        # are being preprocessed        pq = PriorityQueue()Â
        # Insert source itself in priority        # queue and initialize        # its distance as 0        pq.put((0, src))        dist[src] = 0Â
        # Loop till priority queue        # becomes empty (or all        # distances are not finalized)        while not pq.empty():Â
            # The first vertex in pair            # is the minimum distance            # vertex, extract it from            # priority queue            u = pq.get()[1]Â
            # 'i' is used to get all            # adjacent vertices of a vertex            for i in self.adj[u]:Â
                # Get vertex label and                # weight of current                # adjacent of u                v = i[0]                weight = i[1]Â
                # If there is shorted                # path to v through u                if dist[v] > dist[u] + weight:Â
                    # Updating distance of v                    dist[v] = dist[u] + weight                    pq.put((dist[v], v))Â
# Function to return the# required minimum pathdef minPath(V: int, src: int, des: int, g: Graph, r: Graph) -> int:Â
    # Create a vector for    # distances and    # initialize all distances    # as infinite (INF)Â
    # To store distance of all    # vertex from source    dist = [INF for _ in range(V)]Â
    # To store distance of all    # vertex from destination    dist2 = [INF for _ in range(V)]Â
    # To store distance of source    # from all vertex    dist3 = [INF for _ in range(V)]Â
    # To store distance of    # destination from all vertex    dist4 = [INF for _ in range(V)]Â
    # Computing shortest path from    # source vertex to all vertices    g.shortestPath(src, dist)Â
    # Computing shortest path from    # destination vertex to all vertices    g.shortestPath(des, dist2)Â
    # Computing shortest path from    # all the vertices to source    r.shortestPath(src, dist3)Â
    # Computing shortest path from    # all the vertices to destination    r.shortestPath(des, dist4)Â
    # Finding the intermediate node (IN)    # such that the distance of path    # src -> IN -> des -> IN -> src is minimumÂ
    # To store the shortest distance    ans = INT_MAX    for i in range(V):Â
        # Intermediate node should not be        # the source and destination        if (i != des and i != src):            ans = min(ans, dist[i] + dist2[i] + dist3[i] + dist4[i])Â
    # Return the minimum path required    return ansÂ
# Driver codeif __name__ == "__main__":Â
    # Create the graph    V = 5    src = 0    des = 1Â
    # To store the original graph    g = Graph(V)Â
    # To store the reverse graph    # and compute distance from all    # vertex to a particular vertex    r = Graph(V)Â
    # Adding edges    g.addEdge(0, 2, 1)    g.addEdge(0, 4, 5)    g.addEdge(1, 4, 1)    g.addEdge(2, 0, 10)    g.addEdge(2, 3, 5)    g.addEdge(3, 1, 1)    g.addEdge(4, 0, 5)    g.addEdge(4, 2, 100)    g.addEdge(4, 3, 5)Â
    # Adding edges in reverse direction    r.addEdge(2, 0, 1)    r.addEdge(4, 0, 5)    r.addEdge(4, 1, 1)    r.addEdge(0, 2, 10)    r.addEdge(3, 2, 5)    r.addEdge(1, 3, 1)    r.addEdge(0, 4, 5)    r.addEdge(2, 4, 100)    r.addEdge(3, 4, 5)Â
    print(minPath(V, src, des, g, r))Â
# This code is contributed by sanjeev2552 |
C#
// C# implementation of the approachÂ
using System;using System.Collections.Generic;Â
// Priority Queueclass PriorityQueue<T> where T : IComparable<T>{Â Â Â Â private List<Tuple<T, int>> queue = new List<Tuple<T, int>>();Â
    public void Enqueue(T item, int priority)    {        queue.Add(new Tuple<T, int>(item, priority));        queue.Sort((a, b) => a.Item2.CompareTo(b.Item2));    }Â
    public Tuple<T, int> Dequeue()    {        var item = queue[0];        queue.RemoveAt(0);        return item;    }Â
    public bool IsEmpty()    {        return queue.Count == 0;    }}Â
// This class represents// a directed graph using// adjacency list representationclass Graph{    // Number of vertices    private int V;    private List<Tuple<int, int>>[] adj;Â
    public Graph(int V)    {                 this.V = V;    // In a weighted graph, store vertex    // and weight pair for every edge        adj = new List<Tuple<int, int>>[V];        for (int i = 0; i < V; i++)        {            adj[i] = new List<Tuple<int, int>>();        }    }// Function to add an edge to graph    public void AddEdge(int u, int v, int w)    {        adj[v].Add(new Tuple<int, int>(u, w));    }Â
// Function to find the shortest paths// from source to all other vertices    public void ShortestPath(int src, int[] dist)    {             // Create a priority queue to store vertices that    // are being preprocessed        var pq = new PriorityQueue<int>();Â
    // Insert source and initialize    // its distance as 0        pq.Enqueue(src, 0);        dist[src] = 0;Â
    // Loop till priority queue    // becomes empty        while (!pq.IsEmpty())        {        // The first vertex in pair        // is the minimum distance        // vertex, extract it from        // priority queue            var u = pq.Dequeue().Item1;Â
           // 'i' is used to get all        // adjacent vertices of a vertex            foreach (var item in adj[u])            {                var v = item.Item1;                var weight = item.Item2;                  // If there is shorted            // path to v through u                if (dist[v] > dist[u] + weight)                {                    dist[v] = dist[u] + weight;                    pq.Enqueue(v, dist[v]);                }            }        }    }}Â
class Program{    // Function to return the// required minimum path    static int MinPath(int V, int src, int des, Graph g, Graph r)    {        const int INF = 0x3f3f3f3f;Â
    // To store distance of all    // vertex from source        var dist = new int[V];             // To store distance of all    // vertex from destination        var dist2 = new int[V];         // To store distance of all    // vertex from destination        var dist3 = new int[V];         // To store distance of all    // vertex from source        var dist4 = new int[V];Â
        for (int i = 0; i < V; i++)        {            dist[i] = INF;            dist2[i] = INF;            dist3[i] = INF;            dist4[i] = INF;        }Â
// Computing shortest path from// source vertex to all vertices        g.ShortestPath(src, dist);         // Computing shortest path from// destination vertex to all vertices        g.ShortestPath(des, dist2);Â
// Computing shortest path from// all the vertices to source        r.ShortestPath(src, dist3);Â
// Computing shortest path from// all the vertices to destination        r.ShortestPath(des, dist4);Â
// To store the shortest distance        int ans = INF;        for (int i = 0; i < V; i++)        {            if (i != src && i != des)            {                ans = Math.Min(ans, dist[i] + dist2[i] + dist3[i] + dist4[i]);            }        }Â
        return ans;    }Â
// Driver codestatic void Main(string[] args)    {             // To store the original graph        int V = 5;        int src = 0;        int des = 1;Â
           // To store the original graph        var g = new Graph(V);      // Adding edges    g.AddEdge(0, 2, 1);    g.AddEdge(0, 4, 5);    g.AddEdge(1, 4, 1);    g.AddEdge(2, 0, 10);    g.AddEdge(2, 3, 5);    g.AddEdge(3, 1, 1);    g.AddEdge(4, 0, 5);    g.AddEdge(4, 2, 100);    g.AddEdge(4, 3, 5);      // To store the reverse graph    // and compute distance from all    // vertex to a particular vertex    var r = new Graph(V);      // Adding edges in reverse direction    r.AddEdge(2, 0, 1);    r.AddEdge(4, 0, 5);    r.AddEdge(4, 1, 1);    r.AddEdge(0, 2, 10);    r.AddEdge(3, 2, 5);    r.AddEdge(1, 3, 1);    r.AddEdge(0, 4, 5);    r.AddEdge(2, 4, 100);    r.AddEdge(3, 4, 5);Â
    Console.WriteLine(MinPath(V, src, des, g, r));    }} |
Javascript
// JS implementation of the approachÂ
class PriorityQueue {Â Â constructor() {Â Â Â Â this.queue = [];Â Â }Â
  enqueue(node, priority) {    this.queue.push({ node, priority });    this.queue.sort((a, b) => a.priority - b.priority);  }Â
  dequeue() {    return this.queue.shift();  }Â
  isEmpty() {    return this.queue.length === 0;  }}// This class represents// a directed graph using// adjacency list representationclass Graph {  constructor(V) {          // Number of vertices    this.V = V;           // In a weighted graph, store vertex    // and weight pair for every edge    this.adj = Array.from({ length: V }, () => []);  }     // Function to add an edge to graph  addEdge(u, v, w) {    this.adj[v].push([u, w]);  }Â
// Function to find the shortest paths// from source to all other vertices  shortestPath(src, dist) {           // Create a priority queue to    // store vertices that    // are being preprocessed    const pq = new PriorityQueue();          // Insert source itself in priority    // queue and initialize    // its distance as 0    pq.enqueue(src, 0);    dist[src] = 0;       // Loop till priority queue    // becomes empty (or all    // distances are not finalized)    while (!pq.isEmpty()) {                // The first vertex in pair        // is the minimum distance        // vertex, extract it from        // priority queue      const u = pq.dequeue().node;                // 'i' is used to get all        // adjacent vertices of a vertex      for (const [v, weight] of this.adj[u]) {                  // If there is shorted            // path to v through u        if (dist[v] > dist[u] + weight) {                        // Updating distance of v          dist[v] = dist[u] + weight;          pq.enqueue(v, dist[v]);        }      }    }  }}Â
// Function to return the// required minimum pathfunction minPath(V, src, des, g, r) {      const INF = 0x3f3f3f3f;    // Create a vector for    // distances and    // initialize all distances    // as infinite (INF)Â
    // To store distance of all    // vertex from source  const dist = Array.from({ length: V }, () => INF);       // To store distance of all    // vertex from destination  const dist2 = Array.from({ length: V }, () => INF);       // To store distance of all    // vertex from destination  const dist3 = Array.from({ length: V }, () => INF);         // To store distance of    // destination from all vertex  const dist4 = Array.from({ length: V }, () => INF);     // Computing shortest path from    // source vertex to all vertices    g.shortestPath(src, dist);Â
    // Computing shortest path from    // destination vertex to all vertices    g.shortestPath(des, dist2);Â
    // Computing shortest path from    // all the vertices to source    r.shortestPath(src, dist3);Â
    // Computing shortest path from    // all the vertices to destination    r.shortestPath(des, dist4);Â
    // Finding the intermediate node (IN)    // such that the distance of path    // src -> IN -> des -> IN -> src is minimumÂ
    // To store the shortest distanceÂ
  let ans = INF;  for (let i = 0; i < V; i++) {    if (i !== src && i !== des) {      ans = Math.min(ans, dist[i] + dist2[i] + dist3[i] + dist4[i]);    }  }Â
  return ans;}Â
const V = 5;const src = 0;const des = 1;Â
// Driver codeÂ
Â
    // To store the original graphconst g = new Graph(V);Â
    // Adding edgesg.addEdge(0, 2, 1);g.addEdge(0, 4, 5);g.addEdge(1, 4, 1);g.addEdge(2, 0, 10);g.addEdge(2, 3, 5);g.addEdge(3, 1, 1);g.addEdge(4, 0, 5);g.addEdge(4, 2, 100);g.addEdge(4, 3, 5);Â
    // To store the reverse graph    // and compute distance from all    // vertex to a particular vertexconst r = new Graph(V);Â
    // Adding edges in reverse directionr.addEdge(2, 0, 1);r.addEdge(4, 0, 5);r.addEdge(4, 1, 1);r.addEdge(0, 2, 10);r.addEdge(3, 2, 5);r.addEdge(1, 3, 1);r.addEdge(0, 4, 5);r.addEdge(2, 4, 100);r.addEdge(3, 4, 5);Â
console.log(minPath(V, src, des, g, r)); |
17
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!




