Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
All edge weights satisfy . That is the giant neon sign saying: shortest paths from one source are Dijkstra territory.
Keep an array , where is the best distance from node to found so far. Initially, and every other value is .
When processing a node , try every edge . If going through improves , update it:
then set .
Use a min-priority queue of pairs . If you pop and , ignore it. That's just an old queue entry, aka stale garbage.
Build an undirected adjacency list, run standard Dijkstra from source , then print , replacing by .
This is a single-source shortest path problem on an undirected weighted graph. The important part is that every edge has nonnegative weight:
So Dijkstra's algorithm works. No Bellman-Ford drama, no negative-cycle horror movie, just the standard tool doing standard-tool things.
Let
be the shortest distance currently known from node to node .
Initialize:
and for every other node:
We store graph edges in an adjacency list. Since the graph is undirected, every input edge is inserted twice: once as and once as .
When we know a candidate distance to node , we try to improve all neighbors connected by an edge of weight .
The transition is:
then update:
This is called relaxing an edge. Fancy name, simple idea: "can I get there cheaper through here?"
Dijkstra always expands the currently closest unprocessed-looking node. We use a min-priority queue containing pairs:
C++'s priority_queue is max-first by default, so we use greater<> to make it a min-heap.
A node can enter the queue multiple times if we later find a better distance. When we pop a pair , we check:
If true, that entry is outdated and we skip it. This keeps the implementation short and clean.
After Dijkstra finishes, every reachable node has its shortest distance in . If is still , then node is unreachable from node .
Print values for nodes:
one per line, replacing unreachable distances by .
Each edge relaxation can push into the priority queue, so the complexity is:
Memory usage is:
With , this is hilariously safe. The constraints are basically a warm blanket.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int n, m;
cin >> n >> m;
vector<vector<pair<int, int>>> graph(n + 1);
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
graph[u].push_back({v, w});
graph[v].push_back({u, w});
}
const ll INF = (1LL << 60);
vector<ll> dist(n + 1, INF);
dist[1] = 0;
priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
pq.push({0, 1});
while (!pq.empty()) {
auto [d, u] = pq.top();
pq.pop();
if (d != dist[u]) continue;
for (auto [v, w] : graph[u]) {
if (dist[v] > d + w) {
dist[v] = d + w;
pq.push({dist[v], v});
}
}
}
for (int v = 2; v <= n; v++) {
if (dist[v] == INF) cout << -1 << '\n';
else cout << dist[v] << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int n, m;
cin >> n >> m;
vector<vector<pair<int, int>>> graph(n + 1);
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
graph[u].push_back({v, w});
graph[v].push_back({u, w});
}
const ll INF = (1LL << 60);
vector<ll> dist(n + 1, INF);
dist[1] = 0;
priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;
pq.push({0, 1});
while (!pq.empty()) {
auto [d, u] = pq.top();
pq.pop();
if (d != dist[u]) continue;
for (auto [v, w] : graph[u]) {
if (dist[v] > d + w) {
dist[v] = d + w;
pq.push({dist[v], v});
}
}
}
for (int v = 2; v <= n; v++) {
if (dist[v] == INF) cout << -1 << '\n';
else cout << dist[v] << '\n';
}
return 0;
}