#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#define INF 0x3f3f3f3f
using namespace std;
int N=0,last[1000001],dis[1000001],vis[1000001],n;
struct node{
int id,Dis;
friend bool operator < (node A,node B){
if(A.Dis==B.Dis) return A.id>B.id;
return A.Dis>B.Dis;
}
};
struct Node{
int to,edge,next;
}line[1000001];
void add(int add_x,int add_y,int add_z){
line[++N].to=add_y;
line[N].edge=add_z;
line[N].next=last[add_x];
last[add_x]=N;
}
priority_queue<node> q;
int dijkstra(int start){
memset(dis,INF,sizeof(dis));
dis[start]=0;
node useless;
useless.id=start;
useless.Dis=0;
q.push(useless);
while(!q.empty()){
node p=q.top();
q.pop();
if(vis[p.id]) continue;
vis[p.id]=1;
for(int i=last[p.id];i;i=line[i].next){
int To=line[i].to;
if(vis[To]) continue;
if(dis[p.id]+line[i].edge<dis[To]){
dis[To]=dis[p.id]+line[i].edge;
node o;
o.id=To;
o.Dis=dis[To];
q.push(o);
}
}
}
}
int main(){
int m,s;
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
dijkstra(s);
for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
}