#include <bits/stdc++.h>
#define ll long long
#define el '\n'
#define oo LLONG_MAX >> 2
#define all(x) x.begin(), x.end()
#define allr(x) x.rbegin(), x.rend()
#define pb push_back
#define pep_Guardiola                                                          \
  ios::sync_with_stdio(0);                                                     \
  cin.tie(0);                                                                  \
  cout.tie(0);
using namespace std;
struct Node {
  int u;
  ll cost;
  int mn, mx;
  Node() = default;
  Node(int u, ll cost, int mn, int mx) : u(u), cost(cost), mn(mn), mx(mx) {}
  bool operator<(const Node &other) const { return cost > other.cost; }
};
signed main() {
  pep_Guardiola int n, m, s, x;
  cin >> n >> m >> s >> x;
  s--;
  vector<vector<pair<int, int>>> adj(n);
  for (int i = 0, u, v, w; i < m; i++)
    cin >> u >> v >> w, u--, v--, adj[u].push_back({v, w}),
        adj[v].push_back({u, w});
  ll dist[n][2][2];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < 2; j++)
      for (int z = 0; z < 2; z++)
        dist[i][j][z] = oo;
  dist[s][0][0] = 0;
  priority_queue<Node> pq;
  pq.push({s, 0, 0, 0});
  while (pq.size()) {
    auto [u, cost, mn, mx] = pq.top();
    pq.pop();
    if (dist[u][mn][mx] < cost)
      continue;
    for (auto &[v, w] : adj[u]) {
      if (dist[v][mn][mx] > cost + w + x)
        pq.push({v, dist[v][mn][mx] = cost + w + x, mn, mx});
      if (!mn && dist[v][1][mx] > cost + 2 * w + x)
        pq.push({v, dist[v][1][mx] = cost + 2 * w + x, 1, mx});
      if (!mx && dist[v][mn][1] > cost + x)
        pq.push({v, dist[v][mn][1] = cost + x, mn, 1});
      if (!mx && !mn && dist[v][1][1] > cost + x + w)
        pq.push({v, dist[v][1][1] = cost + w + x, 1, 1});
    }
  }
  for (int i = 0; i < n; i++)
    if (i != s)
      cout << dist[i][1][1] << ' ';
}