#include
#define LL long long
#define M(a) memset(a,0,sizeof a)
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
const int mxn=10005;
int n,m,s,cnt,len,num;
struct edge
{
int w,to,nxt;
}e[1000005];
queue q;
vector E[mxn],we[mxn];
vector Z[mxn],wz[mxn];
int head[mxn],dis[mxn];
int dis1[mxn],dis2[mxn];
bool vis1[mxn],vis2[mxn];
void add(int u,int v,int w)
{
e[++cnt].to=v,e[cnt].w=w,e[cnt].nxt=head[u],head[u]=cnt;
}
void calc()
{
num=ceil(3*pow((double)n*n*log(n),1.0/3.0));
rep(Case,1,500)
{
rep(i,1,n) dis[i]=1e9;
int u=rand()%n+1;
q.push(u);
dis[u]=0;
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(dis[v]==1e9) q.push(v);
dis[v]=min(dis[v],dis[u]+e[i].w);
}
}
rep(i,1,n) if(dis[i]!=1e9) len=max(len,dis[i]);
}
len=len*3/2;
// printf("num=%d\n",num);
// printf("len=%d\n",len);
}
void ARROW(int s,int t)
{
M(vis1),M(vis2);
memset(dis1,0x3f,sizeof dis1);
memset(dis2,0x3f,sizeof dis2);
rep(i,1,num)
{
int u=s;
vis1[u]=1;
dis1[u]=0;
rep(j,1,len)
{
int sz=E[u].size();
if(sz==0) break;
int index=rand()%sz;
int v=E[u][index];
dis1[v]=min(dis1[v],dis1[u]+we[u][index]);
vis1[v]=1;
u=v;
}
}
rep(i,1,num)
{
int u=t;
vis2[u]=1;
dis2[u]=0;
rep(j,1,len)
{
int sz=Z[u].size();
if(sz==0) break;
int index=rand()%sz;
int v=Z[u][index];
dis2[v]=min(dis2[v],dis2[u]+wz[u][index]);
vis2[v]=1;
u=v;
}
}
int ans=1e9;
rep(i,1,n) if(vis1[i] && vis2[i])
ans=min(ans,dis1[i]+dis2[i]);
printf("%d ",ans);
}
int main()
{
srand(time(0));
scanf("%d%d%d",&n,&m,&s);
rep(i,1,m)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
E[u].push_back(v);
we[u].push_back(w);
Z[v].push_back(u);
wz[v].push_back(w);
}
calc();
rep(t,1,n)
{
ARROW(s,t);
}
return 0;
}