# Find the shortest distance between any pair of two different good nodes

Given a weighted undirected connected graph with N nodes and M edges. Some of the nodes are marked as good. The task is to find the shortest distance between any pair of two different good nodes.
Note: Nodes marked as yellow in the below examples are considered to be good nodes.

Examples:

`Input :`

```Output : 7
Explanation :
Pairs of Good Nodes and distance between them are:
(1 to 3) -> distance: 7,
(3 to 5) -> distance: 9,
(1 to 5) -> distance: 16,
out of which 7 is the minimum.

Input :```

`Output : 4`

Approach: Let us start by thinking of an algorithm to solve a simpler version of the given problem wherein all edges are of weight 1.

• Pick a random good node and perform a BFS from this point and stop at the first level say which contains another good node.
• We know that the minimum distance between any two good nodes can’t be more than s. So we again take a good node at random which is not already taken before and perform a BFS again. If we don’t find any special node in s distance, we terminate the search. If we do, then we update the value of s and repeat the procedure with some other special node taken at random.

We can apply a similar algorithm when weights are multiple.

Below is the implementation of the above approach:

## C++

 `// C++ program to find the shortest pairwise` `// distance between any two different good nodes.` `#include ` `using` `namespace` `std;`   `#define N 100005` `const` `int` `MAXI = 99999999;`   `// Function to add edges` `void` `add_edge(vector > gr[], ``int` `x,` `              ``int` `y, ``int` `weight)` `{` `    ``gr[x].push_back({ y, weight });` `    ``gr[y].push_back({ x, weight });` `}`   `// Function to find the shortest` `// distance between any pair of` `// two different good nodes` `int` `minDistance(vector > gr[], ``int` `n,` `                ``int` `dist[], ``int` `vis[], ``int` `a[], ``int` `k)` `{` `    ``// Keeps minimum element on top` `    ``priority_queue, vector >,` `                   ``greater > > q;`   `    ``// To keep required answer` `    ``int` `ans = MAXI;`   `    ``for` `(``int` `i = 1; i <= n; i++) {` `        ``// If it is not good vertex` `        ``if` `(!a[i])` `            ``continue``;`   `        ``// Keep all vertices not visited` `        ``// and distance as MAXI` `        ``for` `(``int` `j = 1; j <= n; j++) {` `            ``dist[j] = MAXI;` `            ``vis[j] = 0;` `        ``}`   `        ``// Distance from ith vertex to ith is zero` `        ``dist[i] = 0;`   `        ``// Make queue empty` `        ``while` `(!q.empty())` `            ``q.pop();`   `        ``// Push the ith vertex` `        ``q.push({ 0, i });`   `        ``// Count the good vertices` `        ``int` `good = 0;`   `        ``while` `(!q.empty()) {` `            ``// Take the top element` `            ``int` `v = q.top().second;`   `            ``// Remove it` `            ``q.pop();`   `            ``// If it is already visited` `            ``if` `(vis[v])` `                ``continue``;` `            ``vis[v] = 1;`   `            ``// Count good vertices` `            ``good += a[v];`   `            ``// If distance from vth vertex` `            ``// is greater than ans` `            ``if` `(dist[v] > ans)` `                ``break``;`   `            ``// If two good vertices are found` `            ``if` `(good == 2 and a[v]) {` `                ``ans = min(ans, dist[v]);` `                ``break``;` `            ``}`   `            ``// Go to all adjacent vertices` `            ``for` `(``int` `j = 0; j < gr[v].size(); j++) {` `                ``int` `to = gr[v][j].first;` `                ``int` `weight = gr[v][j].second;`   `                ``// if distance is less` `                ``if` `(dist[v] + weight < dist[to]) {` `                    ``dist[to] = dist[v] + weight;` `                    ``q.push({ dist[to], to });` `                ``}` `            ``}` `        ``}` `    ``}`   `    ``// Return the required answer` `    ``return` `ans;` `}`   `// Driver code` `int` `main()` `{` `    ``// Number of vertices and edges` `    ``int` `n = 5, m = 5;`   `    ``vector > gr[N];`   `    ``// Function call to add edges` `    ``add_edge(gr, 1, 2, 3);` `    ``add_edge(gr, 1, 2, 3);` `    ``add_edge(gr, 2, 3, 4);` `    ``add_edge(gr, 3, 4, 1);` `    ``add_edge(gr, 4, 5, 8);`   `    ``// Number of good nodes` `    ``int` `k = 3;`   `    ``int` `a[N], vis[N], dist[N];`   `    ``// To keep good vertices` `    ``a[1] = a[3] = a[5] = 1;`   `    ``cout << minDistance(gr, n, dist, vis, a, k);`   `    ``return` `0;` `}`

## Java

 `// Java program to find the shortest pairwise` `// distance between any two different good nodes.` `import` `java.util.ArrayList;` `import` `java.util.Comparator;` `import` `java.util.PriorityQueue;`   `class` `GFG{`   `static` `class` `Pair ` `{` `    ``int` `first, second;`   `    ``public` `Pair(``int` `first, ``int` `second) ` `    ``{` `        ``this``.first = first;` `        ``this``.second = second;` `    ``}`   `    ``public` `Pair()` `    ``{}` `}`   `static` `final` `int` `N = ``100005``;` `static` `final` `int` `MAXI = ``99999999``;`   `// Function to add edges` `static` `void` `add_edge(ArrayList gr[], ` `                     ``int` `x, ``int` `y, ``int` `weight)` `{` `    ``gr[x].add(``new` `Pair(y, weight));` `    ``gr[y].add(``new` `Pair(x, weight));` `}`   `// Function to find the shortest` `// distance between any pair of` `// two different good nodes` `static` `int` `minDistance(ArrayList gr[], ``int` `n, ` `                       ``int` `dist[], ``int` `vis[],` `                       ``int` `a[], ``int` `k)` `{` `    `  `    ``// Keeps minimum element on top` `    ``PriorityQueue q = ``new` `PriorityQueue<>(` `        ``new` `Comparator()` `    ``{` `        ``public` `int` `compare(Pair p1, Pair p2)` `        ``{` `            ``if` `(p1.first == p2.first)` `            ``{` `                ``return` `p1.second - p2.second;` `            ``}` `            ``return` `p1.first - p2.first;` `        ``}` `    ``});`   `    ``// To keep required answer` `    ``int` `ans = MAXI;`   `    ``for``(``int` `i = ``1``; i <= n; i++)` `    ``{` `        `  `        ``// If it is not good vertex` `        ``if` `(a[i] == ``0``)` `            ``continue``;`   `        ``// Keep all vertices not visited` `        ``// and distance as MAXI` `        ``for``(``int` `j = ``1``; j <= n; j++) ` `        ``{` `            ``dist[j] = MAXI;` `            ``vis[j] = ``0``;` `        ``}`   `        ``// Distance from ith vertex ` `        ``// to ith is zero` `        ``dist[i] = ``0``;`   `        ``// Make queue empty` `        ``while` `(!q.isEmpty())` `            ``q.poll();`   `        ``// Push the ith vertex` `        ``q.add(``new` `Pair(``0``, i));`   `        ``// Count the good vertices` `        ``int` `good = ``0``;`   `        ``while` `(!q.isEmpty())` `        ``{` `            `  `            ``// Take the top element` `            ``int` `v = q.peek().second;`   `            ``// Remove it` `            ``q.poll();`   `            ``// If it is already visited` `            ``if` `(vis[v] != ``0``)` `                ``continue``;` `            ``vis[v] = ``1``;`   `            ``// Count good vertices` `            ``good += a[v];`   `            ``// If distance from vth vertex` `            ``// is greater than ans` `            ``if` `(dist[v] > ans)` `                ``break``;`   `            ``// If two good vertices are found` `            ``if` `(good == ``2` `&& a[v] != ``0``) ` `            ``{` `                ``ans = Math.min(ans, dist[v]);` `                ``break``;` `            ``}`   `            ``// Go to all adjacent vertices` `            ``for``(``int` `j = ``0``; j < gr[v].size(); j++) ` `            ``{` `                ``int` `to = gr[v].get(j).first;` `                ``int` `weight = gr[v].get(j).second;`   `                ``// If distance is less` `                ``if` `(dist[v] + weight < dist[to]) ` `                ``{` `                    ``dist[to] = dist[v] + weight;` `                    ``q.add(``new` `Pair(dist[to], to));` `                ``}` `            ``}` `        ``}` `    ``}`   `    ``// Return the required answer` `    ``return` `ans;` `}`   `// Driver code` `public` `static` `void` `main(String[] args)` `{` `    `  `    ``// Number of vertices and edges` `    ``int` `n = ``5``, m = ``5``;`   `    ``@SuppressWarnings``(``"unchecked"``)` `    ``ArrayList[] gr = ``new` `ArrayList[N];`   `    ``for``(``int` `i = ``0``; i < N; i++) ` `    ``{` `        ``gr[i] = ``new` `ArrayList();` `    ``}`   `    ``// Function call to add edges` `    ``add_edge(gr, ``1``, ``2``, ``3``);` `    ``add_edge(gr, ``1``, ``2``, ``3``);` `    ``add_edge(gr, ``2``, ``3``, ``4``);` `    ``add_edge(gr, ``3``, ``4``, ``1``);` `    ``add_edge(gr, ``4``, ``5``, ``8``);`   `    ``// Number of good nodes` `    ``int` `k = ``3``;`   `    ``int``[] a = ``new` `int``[N], ` `        ``vis = ``new` `int``[N], ` `       ``dist = ``new` `int``[N];`   `    ``// To keep good vertices` `    ``a[``1``] = a[``3``] = a[``5``] = ``1``;`   `    ``System.out.println(minDistance(` `        ``gr, n, dist, vis, a, k));` `}` `}`   `// This code is contributed by sanjeev2552`

## Python3

 `# Python3 program to find the shortest pairwise` `# distance between any two different good nodes.` `from` `heapq ``import` `*`   `N ``=` `100005` `MAXI ``=` `99999999``;`   `# Function to add edges` `def` `add_edge(gr, x, y, weight):` `    ``gr[x].append( (y, weight ));` `    ``gr[y].append((x, weight));`   `# Function to find the shortest` `# distance between any pair of` `# two different good nodes` `def` `minDistance(gr, n, dist, vis, a, k):` `    ``# Keeps minimum element on top` `    ``q ``=` `heapify([])` `  `  `    ``# To keep required answer` `    ``ans ``=` `MAXI;`   `    ``for` `i ``in` `range``(``1``, n ``+` `1``):` `        ``# If it is not good vertex` `        ``if` `not` `(a[i]):` `            ``continue``;`   `        ``# Keep all vertices not visited` `        ``# and distance as MAXI` `        ``for` `j ``in` `range``(``1``, n ``+` `1``):` `            ``dist[j] ``=` `MAXI;` `            ``vis[j] ``=` `0``;`   `        ``# Distance from ith vertex to ith is zero` `        ``dist[i] ``=` `0``;`   `        ``# Make queue empty` `        ``q ``=` `[]`   `        ``# Push the ith vertex` `        ``heappush(q,  (``0``, i ));`   `        ``# Count the good vertices` `        ``good ``=` `0``;`   `        ``while` `q:` `            ``# Take the top element` `            ``v ``=` `q[``0``][``1``]`   `            ``# Remove it` `            ``heappop(q);`   `            ``# If it is already visited` `            ``if` `(vis[v]):` `                ``continue``;` `            ``vis[v] ``=` `1``;` `            `  `            `  `            ``# Count good vertices` `            ``good ``+``=` `a[v];`   `            ``# If distance from vth vertex` `            ``# is greater than ans` `            ``if` `(dist[v] > ans):` `                ``break``;`   `            ``# If two good vertices are found` `            ``if` `(good ``=``=` `2` `and` `a[v]):` `                ``ans ``=` `min``(ans, dist[v]);` `                ``break``;`   `            ``# Go to all adjacent vertices` `            ``for` `j ``in` `range``(``0``, ``len``(gr[v])):` `                ``to ``=` `gr[v][j][``0``];` `                ``weight ``=` `gr[v][j][``1``];`   `                ``# if distance is less` `                ``if` `(dist[v] ``+` `weight < dist[to]):` `                    ``dist[to] ``=` `dist[v] ``+` `weight;` `                    ``heappush(q, (dist[to], to ));`     `    ``# Return the required answer` `    ``return` `ans;`   `# Driver code`   `# Number of vertices and edges` `n ``=` `5` `m ``=` `5``;`   `gr ``=` `[[] ``for` `_ ``in` `range``(N)];`   `# Function call to add edges` `add_edge(gr, ``1``, ``2``, ``3``);` `add_edge(gr, ``1``, ``2``, ``3``);` `add_edge(gr, ``2``, ``3``, ``4``);` `add_edge(gr, ``3``, ``4``, ``1``);` `add_edge(gr, ``4``, ``5``, ``8``);`   `# Number of good nodes` `k ``=` `3``;`   `a ``=` `[``0` `for` `_ ``in` `range``(N)];` `vis ``=` `[``None` `for` `_ ``in` `range``(N)];` `dist ``=` `[``None` `for` `_ ``in` `range``(N)];`   `# To keep good vertices` `a[``1``] ``=` `1` `a[``3``] ``=` `1` `a[``5``] ``=` `1``;`   `print``(minDistance(gr, n, dist, vis, a, k))`   `# This code is contributed by phasing17`

## C#

 `// C# program to find the shortest pairwise` `// distance between any two different good nodes.`   `using` `System;` `using` `System.Linq;` `using` `System.Collections.Generic;`   `class` `Pair ` `{` `    ``public` `int` `first, second;`   `    ``public` `Pair(``int` `first, ``int` `second) ` `    ``{` `        ``this``.first = first;` `        ``this``.second = second;` `    ``}`   `    ``public` `Pair()` `    ``{}` `}`   `class` `GFG{`   `static` `int` `N = 100005;` `static` `int` `MAXI = 99999999;`   `// Function to add edges` `static` `void` `add_edge(List[] gr, ` `                     ``int` `x, ``int` `y, ``int` `weight)` `{` `    ``gr[x].Add(``new` `Pair(y, weight));` `    ``gr[y].Add(``new` `Pair(x, weight));` `}`   `// Function to find the shortest` `// distance between any pair of` `// two different good nodes` `static` `int` `minDistance(List[] gr, ``int` `n, ` `                       ``int``[] dist, ``int``[] vis,` `                       ``int``[] a, ``int` `k)` `{` `    `  `    ``// Keeps minimum element on top` `    ``List q = ``new` `List();`   `    ``// To keep required answer` `    ``int` `ans = MAXI;`   `    ``for``(``int` `i = 1; i <= n; i++)` `    ``{` `        `  `        ``// If it is not good vertex` `        ``if` `(a[i] == 0)` `            ``continue``;`   `        ``// Keep all vertices not visited` `        ``// and distance as MAXI` `        ``for``(``int` `j = 1; j <= n; j++) ` `        ``{` `            ``dist[j] = MAXI;` `            ``vis[j] = 0;` `        ``}`   `        ``// Distance from ith vertex ` `        ``// to ith is zero` `        ``dist[i] = 0;`   `        ``// Make queue empty` `        ``q.Clear();`   `        ``// Push the ith vertex` `        ``q.Add(``new` `Pair(0, i));`   `        ``// Count the good vertices` `        ``int` `good = 0;`   `        ``while` `(q.Count > 0)` `        ``{` `            `  `            ``// Take the top element` `            ``int` `v = q[0].second;`   `            ``// Remove it` `            ``q.RemoveAt(0);`   `            ``// If it is already visited` `            ``if` `(vis[v] != 0)` `                ``continue``;` `            ``vis[v] = 1;`   `            ``// Count good vertices` `            ``good += a[v];`   `            ``// If distance from vth vertex` `            ``// is greater than ans` `            ``if` `(dist[v] > ans)` `                ``break``;`   `            ``// If two good vertices are found` `            ``if` `(good == 2 && a[v] != 0) ` `            ``{` `                ``ans = Math.Min(ans, dist[v]);` `                ``break``;` `            ``}`   `            ``// Go to all adjacent vertices` `            ``for``(``int` `j = 0; j < gr[v].Count; j++) ` `            ``{` `                ``int` `to = gr[v][j].first;` `                ``int` `weight = gr[v][j].second;`   `                ``// If distance is less` `                ``if` `(dist[v] + weight < dist[to]) ` `                ``{` `                    `  `                    ``dist[to] = dist[v] + weight;` `                    ``q.Add(``new` `Pair(dist[to], to));` `                    ``q = q.OrderBy(p0 => p0.first).ThenBy(p0 => p0.second).ToList();   ` `                ``}` `            ``}` `        ``}` `    ``}`   `    ``// Return the required answer` `    ``return` `ans;` `}`   `// Driver code` `public` `static` `void` `Main(``string``[] args)` `{` `    `  `    ``// Number of vertices and edges` `    ``int` `n = 5;`   `    ``List[] gr = ``new` `List[N];`   `    ``for``(``int` `i = 0; i < N; i++) ` `    ``{` `        ``gr[i] = ``new` `List();` `    ``}`   `    ``// Function call to add edges` `    ``add_edge(gr, 1, 2, 3);` `    ``add_edge(gr, 1, 2, 3);` `    ``add_edge(gr, 2, 3, 4);` `    ``add_edge(gr, 3, 4, 1);` `    ``add_edge(gr, 4, 5, 8);`   `    ``// Number of good nodes` `    ``int` `k = 3;`   `    ``int``[] a = ``new` `int``[N], ` `        ``vis = ``new` `int``[N], ` `       ``dist = ``new` `int``[N];`   `    ``// To keep good vertices` `    ``a[1] = a[3] = a[5] = 1;`   `   ``Console.WriteLine(minDistance(` `        ``gr, n, dist, vis, a, k));` `}` `}`   `// This code is contributed by phasing17`

## Javascript

 `// JS program to find the shortest pairwise` `// distance between any two different good nodes.`   `let N = 100005` `let MAXI = 99999999;`   `// Function to add edges` `function` `add_edge(gr, x, y, weight)` `{` `    ``gr[x].push([ y, weight ]);` `    ``gr[y].push([ x, weight ]);` `}`   `// Function to find the shortest` `// distance between any pair of` `// two different good nodes` `function` `minDistance(gr, n, dist, vis, a, k)` `{` `    ``// Keeps minimum element on top` `    ``let q = [];`   `    ``// To keep required answer` `    ``let ans = MAXI;`   `    ``for` `(``var` `i = 1; i <= n; i++) {` `        ``// If it is not good vertex` `        ``if` `(a[i] != 0)` `            ``continue``;`   `        ``// Keep all vertices not visited` `        ``// and distance as MAXI` `        ``for` `(``var` `j = 1; j <= n; j++) {` `            ``dist[j] = MAXI;` `            ``vis[j] = 0;` `        ``}`   `        ``// Distance from ith vertex to ith is zero` `        ``dist[i] = 0;`   `        ``// Make queue empty` `        ``while` `(q.length != 0)` `            ``q.pop();`   `        ``// Push the ith vertex` `        ``q.push([0, i ]);`   `        ``// Count the good vertices` `        ``let good = 0;` `        `  `        ``while` `(q.length != 0) {`   `            ``// Take the top element` `            ``q.sort(``function` `(a, b)` `            ``{` `                ``return` `(a[0] != b[0]) ? (a[0] > b[0]) : (a[1] > b[1])` `            ``})` `            ``let v = q[0][1];`   `            ``// Remove it` `            ``q.shift();`   `            ``// If it is already visited` `            ``if` `(vis[v] != 0)` `                ``continue``;` `            ``vis[v] = 1;`   `            ``// Count good vertices` `            ``good += a[v];`   `            ``// If distance from vth vertex` `            ``// is greater than ans` `            ``if` `(dist[v] > ans)` `                ``break``;`   `            ``// If two good vertices are found` `            ``if` `(good == 2 && (a[v] != 0)) {` `                ``ans = Math.min(1 + ans,1 + dist[v]);` `                ``break``;` `            ``}`   `            ``// Go to all adjacent vertices` `            ``for` `(``var` `j = 0; j < gr[v].length; j++) {` `                ``var` `to = gr[v][j][0];` `                ``var` `weight = gr[v][j][1] + 1;`   `                ``// if distance is less` `                ``if` `(dist[v] + weight < dist[to]) {` `                    ``dist[to] = dist[v] + weight + 1;` `                    ``q.push([dist[to], to]);` `                    `  `                ``}` `            ``}` `        ``}` `        `  `    ``}`   `    ``// Return the required answer` `    ``return` `ans;` `}`     `// Driver code`   `// Number of vertices and edges` `let n = 5, m = 5;`   `let gr = ``new` `Array(N);`   `for` `(``var` `i = 0; i < N; i++)` `    ``gr[i] = []`   `// Function call to add edges` `add_edge(gr, 1, 2, 3);` `add_edge(gr, 1, 2, 3);` `add_edge(gr, 2, 3, 4);` `add_edge(gr, 3, 4, 1);` `add_edge(gr, 4, 5, 8);`     `// Number of good nodes` `let k = 3;`   `let a = ``new` `Array(N).fill(0) ` `let vis = ``new` `Array(N).fill(0)` `let dist = ``new` `Array(N).fill(0);`   `// To keep good vertices` `a[1] = 1` `a[3] = 1` `a[5] = 1;`   `console.log(minDistance(gr, n, dist, vis, a, k));`   `// This code is contributed by phasing17`

Output:

`7`

Time complexity : O(V + E)
Here V is the number of vertices and E is the number of edges in the graph.

Space complexity : O(V+E)
The space complexity is mainly for the adjacency list used to represent the graph and the priority queue used to process the vertices.

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Previous
Next