AC Code:
#include <cstdio>
#include <queue>
using namespace std;
const int mxn=2e9;
int n,m,s,cnt=0;
int first[10005];//记录 一个点 最后的出边 的边编号
int dq[10005],vis[10005];//dp数组 表示从初始点 到当前点的最近距离  vis数组表示哪个节点是否在队列中
struct node{
    int back,to,cd;//back是 当前边的 上一条边  to表示当前边的目的节点号,cd表示当前边的长度
}nm[500005];//结构体表示静态邻接表
void addljb(int from,int to,int dis){
    nm[++cnt].back=first[from];// 第++cnt 条边的上一条边 等于 以from为起点 上一次 的 出边的编号
    nm[cnt].to=to; //当前的边 通往哪个节点
    nm[cnt].cd=dis;//当前边的长度
    first[from]=cnt; //最后 把  以from为起点的 最后一条出边 赋值给当前 边的编号
}
void spfa(){
    queue<int> quq;
    for(int i=1;i<=n;i++){
        dq[i]=mxn; //带权图初始化
        vis[i]=0;//i是否在队列中
    }
    dq[s]=0;vis[s]=1;quq.push(s);
    while(!quq.empty()){
        int qwq=quq.front();//取出队首
        quq.pop();vis[qwq]=0;//出队标记
        //遍历qwq为起点的所有出边
        for(int i=first[qwq];i;i=nm[i].back){//遍历 静态邻接表 ,以qwq为起点的最后一条边,开始
            int bian=nm[i].to;
            if(dq[bian]>dq[qwq]+nm[i].cd){//如果有最短路就更改
                dq[bian]=dq[qwq]+nm[i].cd;
                if(!vis[bian]){//未入队则入队
                    vis[bian]=1;//标记入队
                    quq.push(bian);
                }
            }
            
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&s);
    int f,g,w;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&f,&g,&w);
        addljb(f,g,w);//建图,有向图连一次边就可以了
    }
    spfa();
    for(int i=1;i<=n;i++){
        if(dq[i]==mxn)printf("2147483647 ");
        else printf("%d ",dq[i]);
    }
    return 0;
}