#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;

typedef long long ll;
typedef pair<ll, int> pii;

const ll INF = 1e18;
const int MAXN = 100005;

vector<vector<pii>> graph;
vector<ll> dist;

void dijkstra(int start, int n) {
    dist.assign(n + 1, INF);
    dist[start] = 0;
    
    priority_queue<pii, vector<pii>, greater<pii>> pq;
    pq.push({0, start});
    
    while (!pq.empty()) {
        ll current_dist = pq.top().first;
        int u = pq.top().second;
        pq.pop();
        
        // 重要:如果当前距离大于已知最短距离,跳过
        if (current_dist != dist[u]) continue;
        
        for (auto &edge : graph[u]) {
            int v = edge.first;
            ll weight = edge.second;
            
            // 松弛操作
            if (dist[u] + weight < dist[v]) {
                dist[v] = dist[u] + weight;
                pq.push({dist[v], v});
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m, S;
    cin >> n >> m >> S;
    
    graph.resize(n + 1);
    
    // 读入图 - 无向图,需要双向添加
    for (int i = 0; i < m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        graph[u].push_back({v, w});
        graph[v].push_back({u, w});  // 无向图,添加反向边
    }
    
    dijkstra(S, n);
    
    // 输出结果
    for (int i = 1; i <= n; i++) {
        if (dist[i] == INF) {
            cout << -1 << "\n";
        } else {
            cout << dist[i] << "\n";
        }
    }
    
    return 0;
}