# Shortest distance between two nodes in Graph by reducing weight of an edge by half

Given a weighted undirected graph consisting of **N** nodes and **M** edges, the task is to find the shortest distance between two nodes **A** and **B** by reducing the weight of one edge by half.

**Examples:**

Input:A = 0, B = 2, Below is the graph

Output:8Explaination:

After reducing the weight of the edge connecting 1 and 2 by half modifies its new weight to 4. Now, the shortest distance to reach 2 from 0 through the path 0 -> 1 -> 2 is (4 + 4) = 8.

Therefore, print 8.

**Approach:** The given problem can be solved by maintaining two arrays, the shortest distance array taking source node as A which will store the shortest distance of all nodes from **A**, and similarly the shortest distance array taking source node as **B**. These arrays can be calculated using Dijkstra’s algorithm. Follow the below steps to solve the above problem:

- Use Dijkstra’s algorithm to store the shortest distance of each node from
**A**into an array**disA[]**. - Use Dijkstra’s algorithm to store the shortest distance of each node from
**B**into an array**disB[]**. - Suppose edge
_{i }=**{u**i.e., edge_{i}, v_{i}, wt_{i}}_{i}connects node**u**to_{i}**v**and has a weight of_{i}**wt**._{i} - Now, iterate over all edges and for every edge keep track of the function as:

f(edge._{i}) = min( disA[u_{i}] + disB[v_{i}], disA[v_{i}] + disB[u_{i}]) + (wt_{i}/2)

- The above relation gives the minimum value of
**f(edge)**, which is the resultant shortest distance.

Below is the implementation of the above approach:

## C++14

`// C++ program for the above approach` `#include <bits/stdc++.h>` `using` `namespace` `std;` `// Stores the input Graph` `vector<pair<` `int` `, ` `int` `> > graph[100001];` `// Stores edges of input Graph` `vector<vector<` `int` `> > edges;` `// Function to input Edges` `void` `add_edge(` `int` `u, ` `int` `v, ` `int` `w)` `{` ` ` `graph[u].push_back({ v, w });` ` ` `graph[v].push_back({ u, w });` ` ` `edges.push_back({ u, v, w });` `}` `// Function to find the shortest distance` `// to each node from the src node using` `// Dijkstraâ€™s Algorithm` `vector<` `int` `> dijsktras(` `int` `src, ` `int` `N)` `{` ` ` `// Stores the shortest distance of` ` ` `// each node form src node` ` ` `vector<` `int` `> dis(N, INT_MAX);` ` ` `vector<` `bool` `> vis(N, ` `false` `);` ` ` `// Stores the node and current` ` ` `// minimum distance in a heap` ` ` `priority_queue<pair<` `int` `, ` `int` `>,` ` ` `vector<pair<` `int` `, ` `int` `> >,` ` ` `greater<pair<` `int` `, ` `int` `> > >` ` ` `pq;` ` ` `pq.push({ 0, src });` ` ` `dis[src] = 0;` ` ` `// BFS for single source shortest` ` ` `// path algorithm` ` ` `while` `(!pq.empty()) {` ` ` `// Top of the PQ` ` ` `auto` `cur = pq.top();` ` ` `pq.pop();` ` ` `// Store the node and weight` ` ` `int` `node = cur.second;` ` ` `int` `weight = cur.first;` ` ` `// If node is already visited` ` ` `if` `(vis[node])` ` ` `continue` `;` ` ` `vis[node] = ` `true` `;` ` ` `// Traverse the adjacency list` ` ` `// of the node` ` ` `for` `(` `auto` `child : graph[node]) {` ` ` `// If the distance obtained` ` ` `// from parent is less than` ` ` `// the current minimum` ` ` `// distance stored for child` ` ` `if` `(dis[child.first]` ` ` `> child.second + weight) {` ` ` `dis[child.first] = weight` ` ` `+ child.second;` ` ` `// Push the next pair` ` ` `// in the PQ` ` ` `pq.push({ dis[child.first],` ` ` `child.first });` ` ` `}` ` ` `}` ` ` `}` ` ` `// Return the maximum distance` ` ` `return` `dis;` `}` `// Function to find shortest distance` `// between two nodes by reducing any` `// one weight of an edge by half` `int` `shortestDistance(` `int` `N, ` `int` `M,` ` ` `int` `A, ` `int` `B)` `{` ` ` `// Stores the the shortest distance` ` ` `// of each node from A` ` ` `vector<` `int` `> disA = dijsktras(A, N);` ` ` `// Stores the the shortest distance` ` ` `// of each node from B` ` ` `vector<` `int` `> disB = dijsktras(B, N);` ` ` `int` `ans = disA[B];` ` ` `for` `(` `auto` `edge : edges) {` ` ` `int` `u = edge[0], v = edge[1];` ` ` `int` `weight = edge[2];` ` ` `// Calculate the value of f(edge)` ` ` `// for the current edge` ` ` `int` `cur = min(disA[u] + disB[v],` ` ` `disA[v] + disB[u])` ` ` `+ (weight / 2);` ` ` `// Keep track of the minimum of` ` ` `// f(edge) for all edges` ` ` `ans = min(ans, cur);` ` ` `}` ` ` `// Return Answer` ` ` `return` `ans;` `}` `// Driver Code` `int` `main()` `{` ` ` `int` `N = 9, M = 14, A = 0, B = 2;` ` ` `// Create a Graph` ` ` `add_edge(0, 1, 4);` ` ` `add_edge(1, 2, 8);` ` ` `add_edge(2, 3, 7);` ` ` `add_edge(3, 4, 9);` ` ` `add_edge(4, 5, 10);` ` ` `add_edge(5, 6, 2);` ` ` `add_edge(6, 7, 1);` ` ` `add_edge(7, 0, 8);` ` ` `add_edge(1, 7, 11);` ` ` `add_edge(7, 8, 7);` ` ` `add_edge(2, 8, 2);` ` ` `add_edge(6, 8, 6);` ` ` `add_edge(2, 5, 4);` ` ` `add_edge(3, 5, 14);` ` ` `// Function Call` ` ` `cout << shortestDistance(N, M, A, B);` ` ` `return` `0;` `}` |

**Output:**

8

**Time Complexity:** O(M*log N)**Auxiliary Space:**O(N + M)