#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node {
int v;//目标结点
int dis;//边权
};
const int MAXN = 1000;
const int INF = 10000000;
vector<node> Adj[MAXN];//Adj[u]存放从顶点u可以走到的所有结点
int n, m, s;//顶点个数,边数,起点编号
int d[MAXN];
bool vis[MAXN] = { false };
void Dijkstra(int s)
{
fill(d, d + MAXN, INF);
d[s] = 0;
for (int i = 0; i < n; i++)
{
int u = -1, MIN = INF;
for (int j = 0; j < n; j++)
{
if (vis[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
}
if (u == -1)
return;
vis[u] = true;
for (int k = 0; k < Adj[u].size(); k++)//与邻接矩阵不同的一个循环
{
int s = Adj[u][k].v;
if (vis[s] == false && d[u] + Adj[u][k].dis < d[s])
{
d[s] = d[u] + Adj[u][k].dis;
}
}
}
}
int main()
{
int u, v, w;
cin >> n >> m >> s;//顶点个数,边数,起点编号
for (int i = 0; i < m; i++)
{
struct node p;
cin >> u >> v >> w;
p.dis = w;
p.v = v;
Adj[u].push_back(p);
}
Dijkstra(s);
for (int i = 0; i < n; i++)
{
cout << d[i] << " ";
}
system("pause");
return 0;
}