import java.util.*; public class djstl { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); // n个点 m条边 x为开始点 如1到6 1为开始点 int m = sc.nextInt(); int x = sc.nextInt(); int value[][] = new int[n + 1][n + 1]; int mindis[] = new int[n + 1]; for (int i = 1; i <= n; i++) { // 先初始化 原点为 0 暂时为连线为Integer.MAX_VALUE mindis[i] = Integer.MAX_VALUE; // 最大值简单修改 统一 for (int j = 1; j <= n; j++) { // n!!! if (i == j) value[i][j] = 0; // 自己到自己为0 else value[i][j] = Integer.MAX_VALUE; } } for (int i = 0; i < m; i++) { // 传入数据 有向边以及权重 没变还是Integer.MAX_VALUE int a = sc.nextInt(); int b = sc.nextInt(); int val = sc.nextInt(); value[a][b] = val; if(a == x) mindis[b] = val; //这里有说明目标点到 过程点的距离是多少 } search( x, mindis , value, n) ; } private static void search(int x, int dis[] , int value[][],int n) { boolean mark[] = new boolean [n+1]; for(int i = 0 ; i <= n ;i++) { //初始化 mark[i] = false; } mark[x] = true; //目标点到自己的位置 的 初始 dis[x] = 0; int count =1; while(count <= n) { int loc = 0; int min = Integer.MAX_VALUE; for(int i =1 ; i <= n ;i++) { if(!mark[i]&&min>value[x][i]) { //找第次次最小的点 loc = i ; //记录第次次最小点所对应的地址 min = value[x][i]; //附上最小值 } } if(loc == 0)break ; //没进去过 直接跳出 mark[loc] = true ; //查找过直接就 true count ++; //while更新数组 for(int i = 1 ; i <= n ; i ++) { if(!mark[i]&&dis[loc]+value[loc][i]<dis[i]&&value[loc][i]!=Integer.MAX_VALUE) { //无路可走 value[loc][i]loc 去i 所对应的权重// dis[loc]目标点到过程所对应的权重 dis[i] = dis[loc]+value[loc][i]; } } } for(int i = 0 ; i <= n ; i++) { if(dis[i]==Integer.MAX_VALUE) { System.out.print(" "+0); i++; } System.out.print(" "+dis[i]); } } }