import std.algorithm, std.array, std.container, std.range, std.bitmanip; import std.numeric, std.math, std.bigint, std.random, core.bitop; import std.string, std.regex, std.conv, std.stdio, std.typecons; void main() { auto rd1 = readln.split.map!(to!size_t); auto n = rd1[0], m = rd1[1], s = rd1[2], t = rd1[3]; auto g = new Graph!int(n); foreach (_; 0..m) { auto rd2 = readln.split; auto a = rd2[0].to!size_t, b = rd2[1].to!size_t, c = rd2[2].to!int; g[a, b] = g[b, a] = c; } auto di = g.dijkstra(t); size_t[] calc(size_t[] r, int rest) { auto c = r.back; if (c == t) return r; foreach (i; 0..n) if (c != i && !g.isInf(c, i) && rest == g[c, i] + di[i]) return calc(r ~ i, rest - g[c, i]); assert(0); } writeln(calc([s], di[s]).map!(to!string).join(" ")); } import std.algorithm, std.container; class Mat(T) { size_t n; // size T[][] v; // values this(size_t n) { this.n = n; v = new T[][](n, n); } T opIndex(size_t i, size_t j) { return v[i][j]; } T opIndexAssign(T w, size_t i, size_t j) { v[i][j] = w; return w; } } class MatHasInf(T) : Mat!T { T inf; // infinite this(size_t n, T inf = -1) { super(n); this.inf = inf; } bool isInf(size_t i, size_t j) { return v[i][j] == inf; } } class Graph(T) : MatHasInf!T { this(size_t n, T inf = -1) { super(n, inf); foreach (i; 0..n) v[i][] = inf; foreach (i; 0..n) v[i][i] = 0; } T[] dijkstra(size_t s) { struct qitem { size_t v; T w; int opCmp(qitem rhs) { return w == rhs.w ? 0 : (w < rhs.w ? -1 : 1); } } auto qi = heapify!("a > b")(Array!qitem()); auto di = new T[](n); di[] = inf; void addNext(qitem q) { auto v = q.v, w = q.w; di[v] = w; foreach (i; 0..n) if (!isInf(v, i) && di[i] == inf) qi.insert(qitem(i, w + this[v, i])); } addNext(qitem(s, 0)); while (!qi.empty) { auto q = qi.front; qi.removeFront; if (di[q.v] != inf) continue; addNext(q); } return di; } }