# Shortest distance between given nodes in a bidirectional weighted graph by removing any K edges

• Difficulty Level : Hard
• Last Updated : 11 Oct, 2021

Given a positive integer K and a weighted undirected connected graph of N nodes and E edges as an array Edges[] of the type {u, v, W} representing the edges between Node u and Node v having weight W, the task is to find the shortest distance between the two given nodes S and D after reducing the cost of at most K edges to 0

Examples:

Input: N = 5, K = 1, Edges[][] = {{0, 1, 1}, {0, 4, 1}, {1, 2, 2}, {2, 3, 4},  {4, 3, 7}}, s = 0, d = 3
Output: 1
Explanation:
Below is the graph for the given test case: There are 2 possible routes between 0 and 3 viz. {0->1->2->3} and {0->4->3}
after reducing the distance of edge 4->3 to zero, the second route becomes 0->(4, 3) and hence the minimum distance is 1.

Input: N = 5, K = 2, Edges[][] = {{0, 1, 2}, {0, 2, 3}, {2, 1, 2}, {2, 3, 1}, {3, 1, 2}, {3, 4, 3}, {4, 2, 4}}, s = 0, d = 3
Ouput: 2

Approach: The given problem can be solved using DFS Traversal and storing all possible paths between the two given nodes. Follow the steps below to solve the given problem:

Below is the implementation of the above approach:

## C++

 `// C++ program of the above approach ` `#include ` `using` `namespace` `std; ` ` `  `// Function to get all the possible ` `// paths from the source to destination ` `void` `dfs_all(``int` `n, ``int` `s, ``int` `d, ` `             ``vector > >& graph, ` `             ``vector<``bool``>& vis, ` `             ``vector >& edge_path, ` `             ``vector<``int``>& temp_edge) ` `{ ` `    ``// One possible path, reached node D ` `    ``if` `(s == d) { ` `        ``edge_path.push_back(temp_edge); ` `        ``return``; ` `    ``} ` ` `  `    ``// Mark node s as visited ` `    ``vis[s] = ``true``; ` ` `  `    ``// Calculate number of edges with ` `    ``// node s as connection ` `    ``int` `edges_in_a = graph[s].size(); ` ` `  `    ``// Traverse all the connections ` `    ``// of node s ` `    ``for` `(``int` `i = 0; i < edges_in_a; i++) { ` ` `  `        ``// If the connected node ` `        ``// isn't visited ` `        ``if` `(!vis[graph[s][i].first]) { ` ` `  `            ``// Push back edge value ` `            ``// in temp_edge ` `            ``temp_edge.push_back( ` `                ``graph[s][i].second); ` ` `  `            ``// Call DFS function recursively ` `            ``dfs_all(n, graph[s][i].first, ` `                    ``d, graph, vis, ` `                    ``edge_path, temp_edge); ` ` `  `            ``// Pop back last added edge ` `            ``temp_edge.pop_back(); ` `        ``} ` `    ``} ` ` `  `    ``// Mark s as unvisited for more ` `    ``// possible paths ` `    ``vis[s] = ``false``; ` `} ` ` `  `// Function to find the minimum sum of ` `// edges from source to destination ` `// after reducing at most K cost to 0 ` `int` `getDistance( ` `    ``vector >& edge_path, ``int` `k) ` `{ ` `    ``// Store the shortestDistance ` `    ``int` `shortestDistance = INT_MAX; ` ` `  `    ``// If edge_path vector is empty, ` `    ``// means no path exist ` `    ``if` `(edge_path.empty()) ` `        ``return` `-1; ` ` `  `    ``// Traverse all the vector in ` `    ``// the edge_path ` `    ``for` `(``auto` `x : edge_path) { ` ` `  `        ``// Base Case ` `        ``if` `(k == x.size()) ` `            ``return` `0; ` ` `  `        ``// lets sort the vector in ` `        ``// decreasing order ` `        ``sort(x.begin(), x.end(), greater<``int``>()); ` ` `  `        ``// Find the sum of all the nodes ` `        ``int` `sum = 0; ` ` `  `        ``// Find the sum of k largest nodes ` `        ``int` `ksum = 0; ` ` `  `        ``for` `(``int` `i = 0; i < x.size(); i++) { ` `            ``sum += x[i]; ` `            ``if` `(i < k) ` `                ``ksum += x[i]; ` `        ``} ` ` `  `        ``// If the given shortestDistance ` `        ``// is shortest, then update the ` `        ``// shortestDistance ` `        ``shortestDistance ` `            ``= min(sum - ksum, shortestDistance); ` `    ``} ` ` `  `    ``// Return the shortestDistance ` `    ``return` `shortestDistance; ` `} ` ` `  `// Function to find the minimum sum of ` `// weight of edges among all paths from ` `// source to destination after reducing ` `// at most K cost to 0 ` `int` `solve( ` `    ``vector > > graph, ` `    ``int` `n, ``int` `k, ``int` `src, ``int` `dest) ` `{ ` `    ``// Stores all the vectors of edges for ` `    ``// every path traversed in DFS call ` `    ``vector > edge_path; ` ` `  `    ``// Store the edges of particular path ` `    ``vector<``int``> temp_edge; ` ` `  `    ``// Boolean visited vector ` `    ``vector<``bool``> vis(n, ``false``); ` ` `  `    ``// DFS Call ` `    ``dfs_all(n, src, dest, graph, ` `            ``vis, edge_path, temp_edge); ` ` `  `    ``return` `getDistance(edge_path, k); ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `n = 5, e = 5, k = 1; ` `    ``vector > > graph(n); ` ` `  `    ``// Given Adjacency List ` `    ``graph.push_back(make_pair(1, 1)); ` `    ``graph.push_back(make_pair(0, 1)); ` ` `  `    ``graph.push_back(make_pair(4, 1)); ` `    ``graph.push_back(make_pair(0, 1)); ` ` `  `    ``graph.push_back(make_pair(2, 2)); ` `    ``graph.push_back(make_pair(1, 2)); ` ` `  `    ``graph.push_back(make_pair(3, 4)); ` `    ``graph.push_back(make_pair(2, 4)); ` ` `  `    ``graph.push_back(make_pair(3, 7)); ` `    ``graph.push_back(make_pair(4, 7)); ` ` `  `    ``int` `a = 0, b = 3; ` ` `  `    ``cout << solve(graph, n, k, a, b); ` ` `  `    ``return` `0; ` `}`

Output:

```1
```

Time Complexity: O((N*log N)NN)
Auxiliary Space: O(N2)

Efficient Approach: The above approach can also be optimized at the step where sorting is performed after finding all possible paths. Instead of sorting, the idea is to use MinHeap to calculate the sum of K largest weights in the graph to reduce the time complexity to O(N*log K) for that steps.

Below is the implementation of the above approach:

## C++

 `// C++ program of the above approach ` `#include ` `using` `namespace` `std; ` ` `  `// Function to get all the possible ` `// paths from the source to destination ` `void` `dfs_all(``int` `n, ``int` `s, ``int` `d, ` `             ``vector > >& graph, ` `             ``vector<``bool``>& vis, ` `             ``vector >& edge_path, ` `             ``vector<``int``>& temp_edge) ` `{ ` `    ``// One possible path, reached node D ` `    ``if` `(s == d) { ` `        ``edge_path.push_back(temp_edge); ` `        ``return``; ` `    ``} ` ` `  `    ``// Mark node s as visited ` `    ``vis[s] = ``true``; ` ` `  `    ``// Calculate number of edges with ` `    ``// node s as connection ` `    ``int` `edges_in_a = graph[s].size(); ` ` `  `    ``// Traverse all the connections ` `    ``// of node s ` `    ``for` `(``int` `i = 0; i < edges_in_a; i++) { ` ` `  `        ``// If the connected node ` `        ``// isn't visited ` `        ``if` `(!vis[graph[s][i].first]) { ` ` `  `            ``// Push back edge value ` `            ``// in temp_edge ` `            ``temp_edge.push_back( ` `                ``graph[s][i].second); ` ` `  `            ``// Call DFS function recursively ` `            ``dfs_all(n, graph[s][i].first, ` `                    ``d, graph, vis, ` `                    ``edge_path, temp_edge); ` ` `  `            ``// Pop back last added edge ` `            ``temp_edge.pop_back(); ` `        ``} ` `    ``} ` ` `  `    ``// Mark s as unvisited for more ` `    ``// possible paths ` `    ``vis[s] = ``false``; ` `} ` ` `  `// Function to find the minimum sum of ` `// edges from source to destination ` `// after reducing at most K cost to 0 ` `int` `getDistance( ` `    ``vector >& edge_path, ``int` `k) ` `{ ` `    ``int` `shortestDistance = INT_MAX; ` ` `  `    ``// If edge_path vector is empty, ` `    ``// means no path exist ` `    ``if` `(edge_path.empty()) ` `        ``return` `-1; ` ` `  `    ``// Traverse all the vector in ` `    ``// the edge_path ` `    ``for` `(``auto` `x : edge_path) { ` ` `  `        ``if` `(k == x.size()) ` `            ``return` `0; ` ` `  `        ``// Use heap to store the array ` `        ``priority_queue<``int``, vector<``int``>, ` `                       ``greater<``int``> > ` `            ``minHeap; ` ` `  `        ``// Find the sum of all the nodes ` `        ``int` `sum = 0; ` ` `  `        ``// Find the sum of k largest nodes ` `        ``int` `ksum = 0; ` ` `  `        ``// Find the largest K edges using ` `        ``// minHeap ` `        ``for` `(``int` `i = 0; i < x.size(); i++) { ` `            ``sum += x[i]; ` `            ``ksum += x[i]; ` ` `  `            ``// Pushing edge in MinHeap ` `            ``minHeap.push(x[i]); ` ` `  `            ``// If heap size is K ` `            ``if` `(minHeap.size() > k) { ` `                ``ksum -= minHeap.top(); ` `                ``minHeap.pop(); ` `            ``} ` `        ``} ` ` `  `        ``// If the shortestDistance is ` `        ``// smallest, then update the ` `        ``// shortestDistance ` `        ``shortestDistance ` `            ``= min(sum - ksum, shortestDistance); ` `    ``} ` ` `  `    ``// Return the shortestDistance ` `    ``return` `shortestDistance; ` `} ` ` `  `// Function to find the minimum sum of ` `// weight of edges among all paths from ` `// source to destination after reducing ` `// at most K cost to 0 ` `int` `solve( ` `    ``vector > > graph, ` `    ``int` `n, ``int` `k, ``int` `src, ``int` `dest) ` `{ ` `    ``// Stores all the vectors of edges for ` `    ``// every path traversed in DFS call ` `    ``vector > edge_path; ` ` `  `    ``// Store the edges of particular path ` `    ``vector<``int``> temp_edge; ` ` `  `    ``// Boolean visited vector ` `    ``vector<``bool``> vis(n, ``false``); ` ` `  `    ``// DFS Call ` `    ``dfs_all(n, src, dest, graph, ` `            ``vis, edge_path, temp_edge); ` ` `  `    ``return` `getDistance(edge_path, k); ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `n = 5, e = 5, k = 1; ` `    ``vector > > graph(n); ` ` `  `    ``// Given Adjacency List ` `    ``graph.push_back(make_pair(1, 1)); ` `    ``graph.push_back(make_pair(0, 1)); ` ` `  `    ``graph.push_back(make_pair(4, 1)); ` `    ``graph.push_back(make_pair(0, 1)); ` ` `  `    ``graph.push_back(make_pair(2, 2)); ` `    ``graph.push_back(make_pair(1, 2)); ` ` `  `    ``graph.push_back(make_pair(3, 4)); ` `    ``graph.push_back(make_pair(2, 4)); ` ` `  `    ``graph.push_back(make_pair(3, 7)); ` `    ``graph.push_back(make_pair(4, 7)); ` ` `  `    ``int` `a = 0, b = 3; ` ` `  `    ``cout << solve(graph, n, k, a, b); ` ` `  `    ``return` `0; ` `}`

Output:

```1
```

Time Complexity: O((N*log K)NN)
Auxiliary Space: O(N2)

My Personal Notes arrow_drop_up
Recommended Articles
Page :