#include #include #include #include #include #define repeat(i,n) for (int i = 0; (i) < (n); ++(i)) template bool setmin(T & l, T const & r) { if (not (r < l)) return false; l = r; return true; } using namespace std; struct edge_t { int from, to, cost; }; struct state_t { int v; int cost; }; bool operator < (state_t a, state_t b) { return a.cost > b.cost; } // strict weak ordering const int inf = 1e9+7; int main() { // input int n, m, start, goal; cin >> n >> m >> start >> goal; vector > g(n); repeat (i,m) { edge_t e; cin >> e.from >> e.to >> e.cost; g[e.from].push_back(e); swap(e.from, e.to); g[e.from].push_back(e); } // search vector dist(n, inf); vector from(n, inf); priority_queue que; // dijkstra que.push((state_t) { start, 0 }); while (not que.empty()) { state_t s = que.top(); que.pop(); if (dist[s.v] != inf) continue; dist[s.v] = s.cost; for (auto e : g[s.v]) { if (dist[e.to] == inf) { que.push((state_t) { e.to, dist[e.from] + e.cost }); } else { // to reconstruct the path if (dist[e.to] + e.cost == dist[e.from]) { setmin(from[e.from], e.to); } } } } // reconstruct deque path; for (int v = goal; v != inf; v = from[v]) { path.push_front(v); } // output for (int v : path) cout << v << ' '; cout << endl; return 0; }