#include <bits/stdc++.h>
using namespace std;
// inf = 10^9
const int inf = 1e9;
// Representasi graf dan setup-setup lainnya
vector<pair<int, int>> adjList[100005];
bool vis[100005];
int dst[100005];
int main() {
// inputin graf
// n banyak node, m banyak jalan (edge), start : start dari node yg mana
int n, m, start;
cin >> n >> m >> start;
for(int i = 1; i <= m; i++) {
// u : start, v : end, w : weight (jarak)
int u, v, w;
cin >> u >> v >> w;
// undirected!! jadi butuh dua kali nyimpen (dari u ke v sama v ke u)
adjList[u].push_back(make_pair(v, w));
adjList[v].push_back(make_pair(u, w));
}
// set dst semua node (kecuali start) = inf, vis = false
for(int i = 0; i < n; i++) vis[i] = false, dst[i] = inf;
dst[start] = 0;
// algo dijalankan
// priority_queue dipake untuk menyimpan (dst[node], node) dari terkecil
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
// masukin node start
pq.push(make_pair(dst[start], start));
while(!pq.empty()) {
// dapetin elemen teratas dari pq
int curnode = pq.top().second;
pq.pop();
if(vis[curnode] == true) continue;
// iterate semua neighbor dari curnode
for(auto i : adjList[curnode]) {
int nextnode = i.first, weight = i.second;
// kalo ternyata ada jarak yang minimum, kita update dan push ke pq
if(dst[nextnode] > dst[curnode] + weight) {
dst[nextnode] = dst[curnode] + weight;
pq.push(make_pair(dst[nextnode], nextnode));
}
}
// set visited = true
vis[curnode] = true;
}
for(int i = 0; i < n; i++) cout << dst[i] << ' ';
cout << '\n';
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyBpbmYgPSAxMF45CmNvbnN0IGludCBpbmYgPSAxZTk7CgovLyBSZXByZXNlbnRhc2kgZ3JhZiBkYW4gc2V0dXAtc2V0dXAgbGFpbm55YQp2ZWN0b3I8cGFpcjxpbnQsIGludD4+IGFkakxpc3RbMTAwMDA1XTsKYm9vbCB2aXNbMTAwMDA1XTsKaW50IGRzdFsxMDAwMDVdOwoKaW50IG1haW4oKSB7CiAgICAvLyBpbnB1dGluIGdyYWYKICAgIC8vIG4gYmFueWFrIG5vZGUsIG0gYmFueWFrIGphbGFuIChlZGdlKSwgc3RhcnQgOiBzdGFydCBkYXJpIG5vZGUgeWcgbWFuYQogICAgaW50IG4sIG0sIHN0YXJ0OwogICAgY2luID4+IG4gPj4gbSA+PiBzdGFydDsKICAgIGZvcihpbnQgaSA9IDE7IGkgPD0gbTsgaSsrKSB7CiAgICAgICAgLy8gdSA6IHN0YXJ0LCB2IDogZW5kLCB3IDogd2VpZ2h0IChqYXJhaykKICAgICAgICBpbnQgdSwgdiwgdzsKICAgICAgICBjaW4gPj4gdSA+PiB2ID4+IHc7CiAgICAgICAgLy8gdW5kaXJlY3RlZCEhIGphZGkgYnV0dWggZHVhIGthbGkgbnlpbXBlbiAoZGFyaSB1IGtlIHYgc2FtYSB2IGtlIHUpCiAgICAgICAgYWRqTGlzdFt1XS5wdXNoX2JhY2sobWFrZV9wYWlyKHYsIHcpKTsKICAgICAgICBhZGpMaXN0W3ZdLnB1c2hfYmFjayhtYWtlX3BhaXIodSwgdykpOwogICAgfQogICAgLy8gc2V0IGRzdCBzZW11YSBub2RlIChrZWN1YWxpIHN0YXJ0KSA9IGluZiwgdmlzID0gZmFsc2UKICAgIGZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHZpc1tpXSA9IGZhbHNlLCBkc3RbaV0gPSBpbmY7CiAgICBkc3Rbc3RhcnRdID0gMDsKICAgIC8vIGFsZ28gZGlqYWxhbmthbgogICAgLy8gcHJpb3JpdHlfcXVldWUgZGlwYWtlIHVudHVrIG1lbnlpbXBhbiAoZHN0W25vZGVdLCBub2RlKSBkYXJpIHRlcmtlY2lsCiAgICBwcmlvcml0eV9xdWV1ZTxwYWlyPGludCwgaW50PiwgdmVjdG9yPHBhaXI8aW50LCBpbnQ+PiwgZ3JlYXRlcjxwYWlyPGludCwgaW50Pj4+IHBxOwogICAgLy8gbWFzdWtpbiBub2RlIHN0YXJ0CiAgICBwcS5wdXNoKG1ha2VfcGFpcihkc3Rbc3RhcnRdLCBzdGFydCkpOwogICAgd2hpbGUoIXBxLmVtcHR5KCkpIHsKICAgICAgICAvLyBkYXBldGluIGVsZW1lbiB0ZXJhdGFzIGRhcmkgcHEKICAgICAgICBpbnQgY3Vybm9kZSA9IHBxLnRvcCgpLnNlY29uZDsKICAgICAgICBwcS5wb3AoKTsKICAgICAgICBpZih2aXNbY3Vybm9kZV0gPT0gdHJ1ZSkgY29udGludWU7CiAgICAgICAgLy8gaXRlcmF0ZSBzZW11YSBuZWlnaGJvciBkYXJpIGN1cm5vZGUKICAgICAgICBmb3IoYXV0byBpIDogYWRqTGlzdFtjdXJub2RlXSkgewogICAgICAgICAgICBpbnQgbmV4dG5vZGUgPSBpLmZpcnN0LCB3ZWlnaHQgPSBpLnNlY29uZDsKICAgICAgICAgICAgLy8ga2FsbyB0ZXJueWF0YSBhZGEgamFyYWsgeWFuZyBtaW5pbXVtLCBraXRhIHVwZGF0ZSBkYW4gcHVzaCBrZSBwcQogICAgICAgICAgICBpZihkc3RbbmV4dG5vZGVdID4gZHN0W2N1cm5vZGVdICsgd2VpZ2h0KSB7CiAgICAgICAgICAgICAgICBkc3RbbmV4dG5vZGVdID0gZHN0W2N1cm5vZGVdICsgd2VpZ2h0OwogICAgICAgICAgICAgICAgcHEucHVzaChtYWtlX3BhaXIoZHN0W25leHRub2RlXSwgbmV4dG5vZGUpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvLyBzZXQgdmlzaXRlZCA9IHRydWUKICAgICAgICB2aXNbY3Vybm9kZV0gPSB0cnVlOwogICAgfQogICAgZm9yKGludCBpID0gMDsgaSA8IG47IGkrKykgY291dCA8PCBkc3RbaV0gPDwgJyAnOwogICAgY291dCA8PCAnXG4nOwp9