#include <bits/stdc++.h>
#define INF numeric_limits<int>::max()
using namespace std;
struct node{
int value;
vector<pair<int,int> > edge;
node(int _value){
value = _value;
}
node(){}
};
int find(const vector<node>& graph,int value){
int len = graph.size();
for(int i = 0;i < len;i ++){
if(graph[i].value == value){
return i;
}
}
return -1;
}
void addnode(vector<node>* graph,int value){
node newnode(value);
graph->push_back(newnode);
}
void addedge(vector<node>* graph,int value1,int value2,int weight){
int index1 = find(*graph,value1);
int index2 = find(*graph,value2);
if(index1 < 0 || index2 < 0) return;
graph->at(index1).edge.push_back({index2,weight});
}
struct cmp{
bool operator()(pair<int,long long> a,pair<int,long long> b){
return a.second > b.second;
}
};
vector<long long> dijkstra(const vector<node>& g,int value){
priority_queue<pair<int,long long>,vector<pair<int,long long> >,cmp> pq;
vector<node> graph(g);
int len = graph.size();
vector<long long> res(len,INF);
int start = find(graph,value);
pq.push({start,0});
while(!pq.empty()){
pair<int,long long> p;
p = pq.top();
pq.pop();
int index = p.first;
res[index] = min(res[index],p.second);
for(auto it : graph[index].edge){
pq.push({it.first,p.second + it.second});
}
}
return res;
}
vector<node> graph;
int main(){
int n,m,s;
scanf("%d%d%d",&n,&m,&s);
for(int i = 1;i <= n;i ++){
addnode(&graph,i);
}
for(int i = 0;i < m;i ++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(&graph,u,v,w);
}
vector<long long> res(dijkstra(graph,s));
for(auto it = res.begin();it < res.end();it ++){
if(it == res.end() - 1){
printf("%lld",*it);
continue;
}
printf("%lld ",*it);
}
}