#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 > path(n, vector({ inf })); priority_queue que; // dijkstra que.push((state_t) { start, 0 }); path[start] = vector({ start }); 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 { if (dist[e.to] + e.cost == dist[e.from]) { vector npath = path[e.to]; npath.push_back(e.from); setmin(path[e.from], npath); } } } } // output repeat (i,path[goal].size()) { if (i) cout << ' '; cout << path[goal][i]; } cout << endl; return 0; }