githubEdit

21. Shortest Path Using At Most One Curved Edge

βœ… GFG solution to the Shortest Path Using At Most One Curved Edge problem: find minimum path length using Dijkstra with state tracking for curved edge usage. πŸš€

The problem can be found at the following link: πŸ”— Question Linkarrow-up-right

🧩 Problem Description

You are given an undirected, connected graph with V vertices numbered from 0 to V-1 and E double-edges. Each double-edge connects vertices x and y with two options:

  • A straight edge with weight w1

  • A curved edge with weight w2

Your task is to find the shortest path from vertex a to vertex b such that you can use at most one curved edge in the entire path. If no such path exists, return -1.

πŸ“˜ Examples

Example 1

Input: V = 4, E = 4, a = 1, b = 3, edges[][] = [[0, 1, 1, 4], [0, 2, 2, 4], [0, 3, 3, 1], [1, 3, 6, 5]]
Output: 2
Explanation: 
Path 1 -> 0 -> 3 using straight edges costs 1 + 3 = 4.
But using the curved edge from 0 -> 3 gives 1 + 1 = 2, which is optimal.

Example 2

Input: V = 2, E = 1, a = 0, b = 1, edges[][] = [[0, 1, 4, 1]]
Output: 1
Explanation: 
Take the curved path from 0 to 1 which costs 1.

πŸ”’ Constraints

  • $1 \le V \le 10^6$

  • $0 \le E \le 10^6$

  • $0 \le a, b \le V - 1$

  • $0 \le \text{edges}[i][0], \text{edges}[i][1] \le V-1$

  • $0 \le \text{edges}[i][2], \text{edges}[i][3] \le 10^4$

βœ… My Approach

The optimal approach uses Dijkstra's Algorithm with State Tracking to handle the constraint of using at most one curved edge:

Dijkstra with State Tracking

  1. Graph Representation:

    • Build an adjacency list where each edge stores both straight weight w1 and curved weight w2.

    • Each node can be in two states: curved edge not used (state 0) or already used (state 1).

  2. Distance Array:

    • Maintain a 2D distance array d[V][2] where:

      • d[u][0] = minimum distance to node u without using any curved edge

      • d[u][1] = minimum distance to node u after using exactly one curved edge

    • Initialize all distances to infinity, except d[a][0] = 0.

  3. Priority Queue:

    • Use a min-heap priority queue storing {distance, node, curved_used}.

    • Process nodes in order of increasing distance.

  4. Relaxation:

    • For each neighbor v of current node u:

      • Straight edge: Update d[v][current_state] using w1 if it gives a shorter path.

      • Curved edge: If curved edge hasn't been used yet (state 0), try updating d[v][1] using w2.

  5. Result:

    • Return min(d[b][0], d[b][1]) as the shortest path to destination b.

    • If both are infinity, return -1.

πŸ“ Time and Auxiliary Space Complexity

  • Expected Time Complexity: O((V + E) log V), where V is the number of vertices and E is the number of edges. Each edge is relaxed at most twice (once for each state), and priority queue operations take O(log V) time.

  • Expected Auxiliary Space Complexity: O(V + E), where O(V) is used for the distance array storing two states per vertex, O(E) for the adjacency list, and O(V) for the priority queue in the worst case.

πŸ§‘β€πŸ’» Code (C++)

chevron-right⚑ View Alternative Approaches with Code and Analysishashtag

πŸ“Š 2️⃣ BFS with State Tracking

πŸ’‘ Algorithm Steps:

  1. Use BFS with queue to explore paths level by level.

  2. Track distance for each node in two states: curved edge used or not used.

  3. Process nodes in order of distance using deque for 0-1 BFS optimization.

  4. Return minimum distance to destination considering both states.

πŸ“ Complexity Analysis:

  • Time: ⏱️ O((V + E) log V) - Each edge processed with priority operations

  • Auxiliary Space: πŸ’Ύ O(V + E) - Distance array and queue storage

βœ… Why This Approach?

  • Efficient exploration using deque optimization

  • Natural level-by-level traversal pattern

  • Good for graphs with similar edge weights

Note: This approach results in Time Limit Exceeded (TLE) for large inputs (fails ~1061/1063 test cases due to time constraints).

πŸ†š πŸ” Comparison of Approaches

πŸš€ Approach

⏱️ Time Complexity

πŸ’Ύ Space Complexity

βœ… Pros

⚠️ Cons

🏷️ Dijkstra Priority Queue

🟒 O((V + E) log V)

🟒 O(V + E)

πŸš€ Optimal for sparse graphs

πŸ”§ Complex priority queue handling

πŸ” BFS State Tracking

🟒 O((V + E) log V)

🟒 O(V + E)

πŸ“– Natural level traversal

πŸ’Ύ May TLE on large dense graphs

πŸ† Best Choice Recommendation

🎯 Scenario

πŸŽ–οΈ Recommended Approach

πŸ”₯ Performance Rating

πŸ… Sparse graphs with many nodes

πŸ₯‡ Dijkstra Priority Queue

β˜…β˜…β˜…β˜…β˜…

πŸ“– Dense graphs with similar weights

πŸ₯ˆ BFS State Tracking

β˜…β˜…β˜…β˜…β˜†

β˜• Code (Java)

🐍 Code (Python)

🧠 Contribution and Support

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: πŸ“¬ Any Questions?arrow-up-right. Let's make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Visitor counter

Last updated