#include using namespace std; typedef long long ll; typedef vector vint; typedef pair pint; typedef vector vpint; #define rep(i,n) for(int i=0;i<(n);i++) #define reps(i,f,n) for(int i=(f);i<(n);i++) #define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++) #define all(v) (v).begin(),(v).end() #define pb push_back #define mp make_pair #define fi first #define se second #define chmax(a, b) a = (((a)<(b)) ? (b) : (a)) #define chmin(a, b) a = (((a)>(b)) ? (b) : (a)) const int MOD = 1e9 + 7; const int INF = 1e9; const int MAX_N = 210; vector > G[MAX_N]; vector dijkstra(int start, int goal){//スタートとゴールを逆に vector dist(MAX_N, INF); vector pre(MAX_N, -1);//pre[i] := iの前の頂点 dist[start] = 0;//dist[i] := start->iまでの最短距離 priority_queue, vector >, greater > > que; que.push(make_pair(0, start)); while(!que.empty()){ int cost, u, t;//今までにかかった時間 現在の頂点 cost = que.top().first, u = que.top().second; que.pop(); if(dist[u] < cost) continue; for (auto tmp : G[u]){ int v = tmp.first, time = tmp.second;//隣接する頂点 その頂点まで行く時間 if(dist[v] > dist[u] + time){//u->v dist[v] = dist[u] + time; pre[v] = u; que.push(make_pair(dist[v], v)); } } } //経路復元 vector path; int s = start, t = goal; for (; t != s; t = pre[t]) path.push_back(t); path.push_back(s); return path; //start-> * -> goal startからgoalまでの最短経路(辞書順最小) } signed main(void){ int n, m, s, g; scanf("%d %d %d %d", &n, &m, &s, &g); rep(i, m){ int a, b, c; scanf("%d %d %d", &a, &b, &c); G[a].pb(mp(b, c)); G[b].pb(mp(a, c)); } auto ans = dijkstra(g, s); rep(i, ans.size()){ if(i != ans.size() - 1)printf("%d ", ans[i]); else printf("%d\n", ans[i]); } return 0; }