Given a connected graph with **N** vertices and **M** edges. The task is to find the shortest path from source to the destination vertex such that the difference between adjacent edge weights in the shortest path change from positive to negative and vice versa ( Weight(E1) > Weight(E2) < Weight(E3) …. ). If no such path exists then print **-1**.

**Examples:**

Input:source = 4, destination = 3

Output:19

4 – 2 – 1 – 3 (Edge Weights: 8, 3, 10) and 4 – 1 – 2 – 3 (Edge Weights: 6, 3, 10) are the only valid paths.

Second path takes the minimum cost i.e. 19.

Input:source = 2, destination = 4

Output:-1

No such path exists.

**Approach:** Here, We need to keep two copies of adjacent lists one for positive difference and other for negative difference. Take a Priority Queue as in Dijkstras Algorithm and keep four variables at a time i.e.,

**cost:**To store the cost of the path till current node.**stage:**An integer variable to tell what element needs to be taken next, if the previous value was negative then a positive value needs to be taken else take negative.**weight:**Weight of the last visited node.**vertex:**Last visited vertex.

For every vertex push the adjacent vertices based on the required condition (value of stage). See the code for better understanding.

Below is the implementation of the above approach:

`// C++ implementation of the approach ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` `#define N 100005 ` ` ` `// To store the graph ` `vector<pair<` `int` `, ` `int` `> > incr[N], decr[N]; ` `int` `_incr[N], _decr[N], shortest[N]; ` ` ` `int` `n, m, src, dest, MAXI = 1LL << 30; ` ` ` `// Function to add edges ` `void` `Add_edge(` `int` `x, ` `int` `y, ` `int` `w) ` `{ ` ` ` `incr[x].push_back({ w, y }); ` ` ` `incr[y].push_back({ w, x }); ` ` ` `decr[x].push_back({ -w, y }); ` ` ` `decr[y].push_back({ -w, x }); ` `} ` ` ` `// Function to find the shortest distance from ` `// source to destination ` `int` `Modified_Dijkstra() ` `{ ` ` ` ` ` `// Total cost, stage, weight of previous, vertex ` ` ` `priority_queue<pair<pair<` `int` `, ` `int` `>, pair<` `int` `, ` `int` `> > > q; ` ` ` ` ` `// Sort the edges ` ` ` `for` `(` `int` `i = 1; i <= n; i++) { ` ` ` `sort(incr[i].begin(), incr[i].end()); ` ` ` `sort(decr[i].begin(), decr[i].end()); ` ` ` `} ` ` ` ` ` `for` `(` `int` `i = 1; i <= n; i++) ` ` ` `shortest[i] = MAXI; ` ` ` ` ` `// Push the source vertex ` ` ` `q.push({ { 0, 0 }, { 0, src } }); ` ` ` ` ` `while` `(!q.empty()) { ` ` ` ` ` `// Take the top element in the queue ` ` ` `pair<pair<` `int` `, ` `int` `>, pair<` `int` `, ` `int` `> > FRONT = q.top(); ` ` ` ` ` `// Remove it from the queue ` ` ` `q.pop(); ` ` ` ` ` `// Store all the values ` ` ` `int` `cost = -FRONT.first.first; ` ` ` `int` `stage = FRONT.first.second; ` ` ` `int` `weight = FRONT.second.first; ` ` ` `int` `v = FRONT.second.second; ` ` ` ` ` `// Take the minimum cost for the vertex ` ` ` `shortest[v] = min(shortest[v], cost); ` ` ` ` ` `// If destination vertex has already been visited ` ` ` `if` `(shortest[dest] != MAXI) ` ` ` `break` `; ` ` ` ` ` `// To make difference negative ` ` ` `if` `(stage) { ` ` ` ` ` `// Start from last not visited vertex ` ` ` `for` `(` `int` `i = _incr[v]; i < incr[v].size(); i++) { ` ` ` ` ` `// If we can take the ith vertex ` ` ` `if` `(weight > incr[v][i].first) ` ` ` `q.push({ { -(cost + incr[v][i].first), 0 }, ` ` ` `{ incr[v][i].first, incr[v][i].second } }); ` ` ` `else` `{ ` ` ` ` ` `// To keep the last not visited vertex ` ` ` `_incr[v] = i; ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` ` ` `// To make difference positive ` ` ` `else` `{ ` ` ` ` ` `// Start from last not visited vertex ` ` ` `for` `(` `int` `i = _decr[v]; i < decr[v].size(); i++) { ` ` ` ` ` `// If we can take the ith vertex ` ` ` `if` `(weight < -decr[v][i].first) ` ` ` `q.push({ { -(cost - decr[v][i].first), 1 }, ` ` ` `{ -decr[v][i].first, decr[v][i].second } }); ` ` ` `else` `{ ` ` ` ` ` `// To keep the last not visited vertex ` ` ` `_decr[v] = i; ` ` ` `break` `; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` ` ` `if` `(shortest[dest] == MAXI) ` ` ` `return` `-1; ` ` ` ` ` `return` `shortest[dest]; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `n = 5, src = 4, dest = 3; ` ` ` ` ` `// Adding edges ` ` ` `Add_edge(4, 2, 8); ` ` ` `Add_edge(1, 4, 6); ` ` ` `Add_edge(2, 3, 10); ` ` ` `Add_edge(3, 1, 10); ` ` ` `Add_edge(1, 2, 3); ` ` ` `Add_edge(3, 5, 3); ` ` ` ` ` `cout << Modified_Dijkstra(); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

19

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Shortest path in a graph from a source S to destination D with exactly K edges for multiple Queries
- Shortest Path with even number of Edges from Source to Destination
- Find optimal weights which can be used to weigh all the weights in the range [1, X]
- Sum of shortest distance on source to destination and back having at least a common vertex
- Print all shortest paths between given source and destination in an undirected graph
- Find weight of MST in a complete graph with edge-weights either 0 or 1
- Minimum edges to reverse to make path from a source to a destination
- Minimum cost path from source node to destination node via an intermediate node
- Source to destination in 2-D path with fixed sized jumps
- Shortest Path in a weighted Graph where weight of an edge is 1 or 2
- Maximize shortest path between given vertices by adding a single edge
- Multi Source Shortest Path in Unweighted Graph
- D'Esopo-Pape Algorithm : Single Source Shortest Path
- Single source shortest path between two cities
- Count all possible walks from a source to a destination with exactly k edges
- Print all paths from a given source to a destination
- Print all paths from a given source to a destination using BFS
- Number of Walks from source to destination
- Count total ways to reach destination from source in an undirected Graph
- Check if a destination is reachable from source with two movements allowed | Set 2

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.