Skip to content

Commit 6bab4be

Browse files
authored
Merge pull request #119 from AnjaliPai16/graph_sol
Shortest Routes 1 solution
2 parents 9039c34 + 96415c8 commit 6bab4be

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
Problem: Shortest Routes I
3+
Category: Graph Algorithms (Single Source Shortest Path)
4+
Difficulty: Medium
5+
Time Complexity: O((n + m) * log n)
6+
Space Complexity: O(n + m)
7+
8+
Approach:
9+
This problem asks for the shortest distance from a source city (1) to every other city in a directed, weighted graph.
10+
Since all edge weights are positive, Dijkstra’s Algorithm is the optimal approach.
11+
12+
Steps:
13+
1. Represent the graph using an adjacency list where each node stores pairs (neighbor, weight).
14+
2. Initialize all distances as infinity (INF = 1e18) and set the source city’s distance (city 1) to 0.
15+
3. Use a min-heap (priority queue) to always pick the node with the smallest current distance.
16+
4. For each node popped from the queue:
17+
- If the current distance is greater than the stored distance, skip (outdated entry).
18+
- For all adjacent nodes, relax the edge:
19+
if dist[u] + w < dist[v], update dist[v] and push (dist[v], v) into the priority queue.
20+
5. After processing all nodes, print the distances from city 1 to every city in order.
21+
22+
Key Insights:
23+
- Dijkstra’s algorithm is efficient for graphs with **non-negative weights**, unlike Bellman-Ford.
24+
- Priority queue ensures that each edge relaxation happens optimally, minimizing redundant work.
25+
- Since the problem guarantees that all nodes are reachable from city 1, there’s no need to handle disconnected components.
26+
- Using `long long` (64-bit integers) prevents overflow, as path lengths can exceed 1e9.
27+
- Fast I/O (`ios::sync_with_stdio(false); cin.tie(nullptr);`) is essential due to large input size.
28+
- Memory-efficient representation with adjacency list handles up to 2×10^5 edges comfortably.
29+
30+
Optimization Tricks:
31+
- Avoid reprocessing nodes by checking `if (d > dist[u]) continue;`.
32+
- Store distances in a vector instead of an unordered_map for faster access (since node indices are contiguous).
33+
- Use `greater<pair<int, int>>` with priority_queue for min-heap behavior.
34+
35+
Edge Cases:
36+
- Multiple edges between same nodes → Dijkstra naturally handles it (shorter path replaces longer one).
37+
- Single city (n = 1) → Output is just 0.
38+
- Large input graphs → Must ensure O((n + m) log n) implementation to stay within 1s time limit.
39+
40+
*/
41+
#include <bits/stdc++.h>
42+
using namespace std;
43+
44+
#define int long long
45+
const int INF = 1e18; // Large value representing infinity
46+
47+
int32_t main() {
48+
ios::sync_with_stdio(false);
49+
cin.tie(nullptr);
50+
51+
int n, m;
52+
cin >> n >> m;
53+
54+
vector<vector<pair<int, int>>> adj(n + 1); // {neighbor, weight}
55+
56+
for (int i = 0; i < m; i++) {
57+
int a, b, c;
58+
cin >> a >> b >> c;
59+
adj[a].push_back({b, c});
60+
}
61+
62+
vector<int> dist(n + 1, INF);
63+
dist[1] = 0; // Distance to source is 0
64+
65+
// Min-heap: {distance, node}
66+
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
67+
pq.push({0, 1});
68+
69+
while (!pq.empty()) {
70+
auto [d, u] = pq.top();
71+
pq.pop();
72+
73+
if (d > dist[u]) continue; // Skip outdated entry
74+
75+
for (auto [v, w] : adj[u]) {
76+
if (dist[u] + w < dist[v]) {
77+
dist[v] = dist[u] + w;
78+
pq.push({dist[v], v});
79+
}
80+
}
81+
}
82+
83+
for (int i = 1; i <= n; i++) {
84+
cout << dist[i] << " ";
85+
}
86+
cout << "\n";
87+
88+
return 0;
89+
}

0 commit comments

Comments
 (0)