No big difference with "Breadth First Search: Shortest Reach", but this statement is crucial:
If there are edges between the same pair of nodes with different weights, they are to be considered as is, like multiple edges.
#include <cmath> #include <cstdio> #include <vector> #include <string> #include <iostream> #include <algorithm> #include <queue> #include <unordered_map> #include <unordered_set> using namespace std; typedef pair<int, long> Node; // index - dist const long DIST_MAX = std::numeric_limits<long>::max(); vector<long> dist; struct Comp { int operator() (const Node &n1, const Node &n2) { return n1.second > n2.second; } }; int main() { int t; cin >> t; while (t--) { unordered_map<int, unordered_map<int, int>> g; int n, m; cin >> n >> m; int mm = m; while (mm--){ int x, y, r; cin >> x >> y >> r; x--, y--; if (g[x].find(y) == g[x].end()) g[x][y] = r; else g[x][y] = std::min(g[x][y], r); if (g[y].find(x) == g[y].end()) g[y][x] = r; else g[y][x] = std::min(g[y][x], r); } int s; cin >> s; s--; // dist.assign(n, DIST_MAX); dist[s] = 0; // inx priority_queue<Node, vector<Node>, Comp> hp; hp.push(Node(s, dist[s])); while (!hp.empty()) { Node n = hp.top(); hp.pop(); for (auto &c : g[n.first]) { int j = c.first; int d = c.second; if (dist[j] == DIST_MAX || (dist[n.first] + d) < dist[j]) { dist[j] = dist[n.first] + d; hp.push(Node(j, dist[j])); } } } // output for (int i = 0; i < n; i++) if (i != s) cout << (dist[i] == DIST_MAX ? -1 : dist[i]) << " "; cout << endl; } return 0; }